home *** CD-ROM | disk | FTP | other *** search
/ Euroscene 2 / Euroscene 2.iso / USEFUL / DeliTracker130 / Developer / Developer.run / Examples / MED.s < prev    next >
Encoding:
Text File  |  1992-09-23  |  81.1 KB  |  3,110 lines

  1.  
  2.     incdir    "Includes:"
  3.     include "misc/DeliPlayer.i"
  4.  
  5. ;
  6. ;
  7.     SECTION Player,Code
  8. ;
  9. ;
  10.  
  11.     PLAYERHEADER PlayerTagArray
  12.  
  13.     dc.b '$VER: MED 3.22 player module V1.9 (18 Jul 92)',0
  14.     even
  15.  
  16. PlayerTagArray
  17.     dc.l    DTP_PlayerVersion,3
  18.     dc.l    DTP_PlayerName,PName
  19.     dc.l    DTP_Creator,CName
  20.     dc.l    DTP_Check2,Chk
  21.     dc.l    DTP_InitPlayer,InitPlay
  22.     dc.l    DTP_EndPlayer,EndPlay
  23.     dc.l    DTP_InitSound,InitSnd
  24.     dc.l    DTP_StartInt,StartSnd
  25.     dc.l    DTP_StopInt,StopSnd
  26.     dc.l    DTP_Volume,SetVol
  27.     dc.l    DTP_PrevSong,PrevSub
  28.     dc.l    DTP_NextSong,NextSub
  29.     dc.l    TAG_DONE
  30.  
  31. *-----------------------------------------------------------------------*
  32. ;
  33. ; Player/Creatorname und lokale Daten
  34.  
  35. PName    dc.b 'MED',0
  36. CName    dc.b 'Teijo Kinnunen,',10
  37.     dc.b 'adapted by Delirium',0
  38.     even
  39. med_data    dc.l 0
  40. med_volume    dc.w 0
  41.  
  42. *-----------------------------------------------------------------------*
  43. ;
  44. ; Testet, ob es sich um ein MED-Modul handelt
  45.  
  46. Chk
  47.     move.l    dtg_ChkData(a5),a0
  48.  
  49.     moveq    #-1,d0                ; Modul nicht erkannt (default)
  50.  
  51.     cmpi.l    #"MMD0",(a0)
  52.     beq.s    ChkFlags
  53.  
  54.     cmpi.l    #"MMD1",(a0)
  55.     bne.s    ChkEnd
  56. ChkFlags
  57.     add.l    mmd_songinfo(a0),a0
  58.     btst    #6,msng_flags(a0)        ; =<4 voices ?
  59.     bne.s    ChkEnd
  60.  
  61.     moveq    #0,d0                ; Modul erkannt
  62. ChkEnd
  63.     rts
  64.  
  65. *-----------------------------------------------------------------------*
  66. ;
  67. ; Init Player
  68.  
  69. InitPlay
  70.     moveq    #0,d0
  71.     move.l    dtg_GetListData(a5),a0        ; Function
  72.     jsr    (a0)
  73.     move.l    a0,med_data
  74.  
  75.     move.l    a0,-(sp)
  76.     jsr    _RelocModule
  77.     addq.l    #4,sp
  78.  
  79.     clr.w    dtg_SndNum(a5)            ; first Subsong
  80.  
  81.     jsr    _InitPlayer            ; returncode is already set !
  82.     rts
  83.  
  84. *-----------------------------------------------------------------------*
  85. ;
  86. ; End Player
  87.  
  88. EndPlay
  89.     jsr    _RemPlayer
  90.     rts
  91.  
  92. *-----------------------------------------------------------------------*
  93. ;
  94. ; Init Sound
  95.  
  96. InitSnd
  97.     move.l    med_data(pc),a0            ; ^Module
  98.     jsr    _InitModule
  99.     rts
  100.  
  101. *-----------------------------------------------------------------------*
  102. ;
  103. ; Start Play
  104.  
  105. StartSnd
  106.     move.w    dtg_SndNum(a5),_modnum
  107.     move.l    med_data(pc),a0            ; ^Module
  108.     jsr    _ContModule
  109.     rts
  110.  
  111. *-----------------------------------------------------------------------*
  112. ;
  113. ; Stop Play
  114.  
  115. StopSnd
  116.     jsr    _StopPlayer
  117.     rts
  118.  
  119. *-----------------------------------------------------------------------*
  120. ;
  121. ; Previous SubSong
  122.  
  123. PrevSub
  124.     tst.w    dtg_SndNum(a5)
  125.     beq.s    PrevSubEnd
  126.  
  127.     move.l    dtg_StopInt(a5),a0
  128.     jsr    (a0)
  129.     subq.w    #1,dtg_SndNum(a5)        ; Vorheriger Sound
  130.     move.l    dtg_StartInt(a5),a0
  131.     jsr    (a0)
  132. PrevSubEnd
  133.     rts
  134.  
  135. *-----------------------------------------------------------------------*
  136. ;
  137. ; Next SubSong
  138.  
  139. NextSub
  140.     move.l    med_data(pc),a0
  141.     move.w    dtg_SndNum(a5),d0
  142.     addq.w    #1,d0
  143. NextSubLoop
  144.     tst.l    mmd_expdata(a0)
  145.     beq.s    NextSubEnd
  146.     move.l    mmd_expdata(a0),a1
  147.     tst.l    (a1)
  148.     beq.s    NextSubEnd            ;no more modules here!
  149.     move.l    (a1),a0
  150.     subq.w    #1,d0
  151.     bgt.s    NextSubLoop
  152.  
  153.     move.l    dtg_StopInt(a5),a0
  154.     jsr    (a0)
  155.     addq.w    #1,dtg_SndNum(a5)        ; Nächster Sound
  156.     move.l    dtg_StartInt(a5),a0
  157.     jsr    (a0)
  158. NextSubEnd
  159.     rts
  160.  
  161. *-----------------------------------------------------------------------*
  162. ;
  163. ; Set new volume
  164.  
  165. SetVol
  166.     move.w    dtg_SndVol(a5),med_volume    ; copy to internal buffer
  167.     rts
  168.  
  169. *-----------------------------------------------------------------------*
  170. ;
  171. ; calculate new volume
  172.  
  173. CalcVol
  174.     ext.w    d0
  175.     mulu    med_volume(pc),d0
  176.     lsr.w    #6,d0
  177.     rts
  178.  
  179. *-----------------------------------------------------------------------*
  180. ;
  181. ; Relocate Module
  182.  
  183. ;    Function: _RelocModule()
  184. ;    pointer to the module passed in stack
  185.  
  186. ;    SECTION    "text",code
  187.  
  188.     XDEF    _RelocModule
  189.  
  190. reloci    move.l    24(a2),d0
  191.     beq.s    xloci
  192.     movea.l    d0,a0
  193.     moveq   #0,d0
  194.     move.b  787(a1),d0    ;number of samples
  195.     subq.b  #1,d0
  196. relocs:    bsr.s   relocentr
  197.     move.l    -4(a0),d3    ;sample ptr
  198.     beq.s    nosyn
  199.     move.l    d3,a3
  200.     tst.w    4(a3)
  201.     bpl.s    nosyn        ;type >= 0
  202.     move.w    20(a3),d2    ;number of waveforms
  203.     lea    278(a3),a3    ;ptr to wf ptrs
  204.     subq.w    #1,d2
  205. relsyn:    add.l    d3,(a3)+
  206.     dbf    d2,relsyn
  207. nosyn:    dbf     d0,relocs
  208. xloci    rts
  209. norel    addq.l    #4,a0
  210.     rts
  211. relocentr:
  212.     tst.l   (a0)
  213.     beq.s   norel
  214.     add.l   d1,(a0)+
  215.     rts
  216. _RelocModule:
  217.     move.l    4(sp),a0    ;get module pointer from stack
  218.     movem.l    a2-a3/d2-d3,-(sp)
  219.     movea.l a0,a2
  220.     move.l  a2,d1        ;d1 = ptr to start of module
  221.     bsr.s    relocp
  222.     movea.l 8(a2),a1
  223.     bsr.s    reloci
  224. rel_lp    bsr.s    relocb
  225.     move.l    32(a2),d0    ;extension struct
  226.     beq.s    rel_ex
  227.     move.l    d0,a0
  228.     bsr.s    relocentr    ;ptr to next module
  229.     bsr.s    relocentr    ;InstrExt...
  230.     addq.l    #4,a0        ;skip sizes of InstrExt
  231. ; We reloc the pointers of MMD0exp, so anybody who needs them can easily
  232. ; read them.
  233.     bsr.s    relocentr    ;annotxt
  234.     addq.l    #4,a0        ;annolen
  235.     bsr.s    relocentr    ;InstrInfo
  236.     addq.l    #8,a0
  237.     bsr.s    relocentr    ;rgbtable (not useful for most people)
  238.     addq.l    #4,a0        ;skip channelsplit
  239.     bsr.s    relocentr    ;NotationInfo
  240.     bsr.s    relocentr    ;songname
  241.     addq.l    #4,a0        ;skip song name length
  242.     bsr.s    relocentr    ;MIDI dumps
  243.     bsr.s    relocmdd
  244.     move.l    d0,a0
  245.     move.l    (a0),d0
  246.     beq.s    rel_ex
  247.     move.l    d0,a2
  248.     bsr.s    relocp
  249.     movea.l 8(a2),a1
  250.     bra.s    rel_lp
  251. rel_ex    movem.l    (sp)+,d2-d3/a2-a3
  252.     rts
  253.  
  254. relocp    lea    8(a2),a0
  255.     bsr.s    relocentr
  256.     addq.l    #4,a0
  257.     bsr.s    relocentr
  258.     addq.l    #4,a0
  259.     bsr.s    relocentr
  260.     addq.l    #4,a0
  261.     bra.s    relocentr
  262.  
  263. relocb    move.l    16(a2),d0
  264.     beq.s    xlocb
  265.     movea.l    d0,a0
  266.     move.w  504(a1),d0
  267.     subq.b  #1,d0
  268. rebl    bsr.s   relocentr
  269.     dbf     d0,rebl
  270.     cmp.b    #'1',3(a2)    ;test MMD type
  271.     beq.s    relocbi
  272. xlocb    rts
  273.  
  274. relocmdd
  275.     tst.l    -(a0)
  276.     beq.s    xlocmdd
  277.     movea.l    (a0),a0
  278.     move.w    (a0),d0        ;# of msg dumps
  279.     addq.l    #8,a0
  280. mddloop    beq.s    xlocmdd
  281.     bsr    relocentr
  282.     bsr.s    relocdmp
  283.     subq.w    #1,d0
  284.     bra.s    mddloop
  285. xlocmdd    rts
  286.  
  287. relocdmp
  288.     move.l    -4(a0),d3
  289.     beq.s    xlocdmp
  290.     exg.l    a0,d3        ;save
  291.     addq.l    #4,a0
  292.     bsr    relocentr    ;reloc data pointer
  293.     move.l    d3,a0        ;restore
  294. xlocdmp    rts
  295.  
  296. relocbi    move.w    504(a1),d0
  297.     move.l    a0,a3
  298. biloop    subq.w    #1,d0
  299.     bmi.s    xlocdmp
  300.     move.l    -(a3),a0
  301.     addq.l    #4,a0
  302.     bsr    relocentr    ;BlockInfo ptr
  303.     tst.l    -(a0)
  304.     beq.s    biloop
  305.     move.l    (a0),a0
  306.     bsr    relocentr    ;hldata
  307.     bsr    relocentr    ;block name
  308.     bra.s    biloop
  309.  
  310. ;    END
  311.  
  312. *-----------------------------------------------------------------------*
  313. ;
  314. ; Replay Routine
  315.  
  316. ;    proplayer.a
  317. ;    ~~~~~~~~~~~
  318. ; The music player routine for MMD0 and MMD1 MED/OctaMED/OctaMED Professional
  319. ; four-channel modules.
  320.  
  321. ; Written by Teijo Kinnunen.
  322. ; If you find bugs in this routine, please notify:
  323. ;    Teijo Kinnunen
  324. ;    Oksantie 19
  325. ;    SF-86300  OULAINEN
  326. ;    FINLAND
  327. ;
  328. ; THIS CODE MAY BE FREELY USED AND DISTRIBUTED!
  329.  
  330. ;============================================================================
  331.  
  332. MIDI        EQU 0    ;1 = include MIDI code
  333. AUDDEV        EQU 1    ;1 = allocate channels using audio.device
  334. SYNTH        EQU 1    ;1 = include synth-sound handler
  335. CHECK        EQU 1    ;1 = do range checkings (track, sample in mem etc.)
  336. RELVOL        EQU 1    ;1 = include relative volume handling code
  337. IFFMOCT        EQU 1    ;1 = play IFF multi-octave samples correctly
  338. HOLD        EQU 1    ;1 = handle hold/decay
  339. PLAYMMD0    EQU 1    ;1 = play old MMD0 modules
  340. ;****** Timing control ******
  341. VBLANK    EQU    0    ;1 = use VBlank interrupt (when absolutely necessary)
  342. CIAB    EQU    1    ;1 = use CIAB timers (default)
  343. ; Please use CIAB whenever possible to avoid problems with variable
  344. ; VBlank speeds and to allow the use of command F01 - FF0 (set tempo)
  345. ; If both are set to 0, the timing is left for you (never set both to 1!!),
  346. ; then you just call _IntHandler for each timing pulse.
  347.  
  348. ;============================================================================
  349.  
  350. ;If you are making a demo/game with only a single tune you'd like to
  351. ;incorporate in the code (like "easyplayer.a" of MED V3), set the following
  352. ;flag to 1. This requires an assembler with INCBIN (or equivalent) directive.
  353. ;You have to type the module name into the INCBIN statement (located near the
  354. ;end of this file, on line 2052).
  355.  
  356. EASY    EQU    0
  357.  
  358. ;Call _startmusic to play the music, and _endmusic to stop it (before
  359. ;exiting). Note: don't call _startmusic twice!! This would cause the module
  360. ;to be relocated twice (= Guru). If you need to stop and continue playing,
  361. ;don't use the EASY routines, use PlayModule/StopPlayer... instead.
  362.  
  363. ;============================================================================
  364.  
  365. ;the MMD0 structure offsets
  366. mmd_id        EQU    0
  367. mmd_modlen    EQU    4
  368. mmd_songinfo    EQU    8
  369. mmd_blockarr    EQU    16
  370. mmd_smplarr    EQU    24
  371. mmd_expdata    EQU    32
  372. mmd_pstate    EQU    40 ; <0 = play song, 0 = don't play, >0 = play block
  373. mmd_pblock    EQU    42
  374. mmd_pline    EQU    44
  375. mmd_pseqnum    EQU    46
  376. mmd_actplayline    EQU    48
  377. mmd_counter    EQU    50
  378. mmd_songsleft    EQU    51
  379.  
  380. ;the MMD0song structure
  381. ;Instrument data here (504 bytes = 63 * 8)
  382. msng_numblocks    EQU    504
  383. msng_songlen    EQU    506
  384. msng_playseq    EQU    508
  385. msng_deftempo    EQU    764
  386. msng_playtransp    EQU    766
  387. msng_flags    EQU    767
  388. msng_flags2    EQU    768
  389. msng_tempo2    EQU    769
  390. msng_trkvol    EQU    770
  391. msng_mastervol    EQU    786
  392. msng_numsamples    EQU    787
  393.  
  394. ;Instrument data
  395. inst_repeat    EQU    0
  396. inst_replen    EQU    2
  397. inst_midich    EQU    4
  398. inst_midipreset    EQU    5
  399. inst_svol    EQU    6
  400. inst_strans    EQU    7
  401.  
  402. ;Audio hardware offsets
  403. ac_ptr    EQU    $00
  404. ac_len    EQU    $04
  405. ac_per    EQU    $06
  406. ac_vol    EQU    $08
  407.  
  408. ;Trackdata sizes
  409. T03SZ    EQU    98
  410. T415SZ    EQU    20
  411.  
  412.         SECTION    "text",CODE
  413.  
  414.     IFNE    EASY
  415.  
  416.         XDEF    _startmusic,_endmusic
  417.  
  418. _startmusic    lea    easymod,a2
  419.         bsr.s    _RelocModule
  420.         bsr.w    _InitPlayer
  421.         lea    easymod,a0
  422.         bra.w    _PlayModule
  423.  
  424. _endmusic    bra.w    _RemPlayer
  425. ; ***** The relocation routine *****
  426. reloci        move.l    24(a2),d0
  427.         beq.s    xloci
  428.         movea.l    d0,a0
  429.         moveq   #0,d0
  430.         move.b  787(a1),d0    ;number of samples
  431.         subq.b  #1,d0
  432. relocs:        bsr.s   relocentr
  433.         move.l    -4(a0),d3    ;sample ptr
  434.         beq.s    nosyn
  435.         move.l    d3,a3
  436.         tst.w    4(a3)
  437.         bpl.s    nosyn        ;type >= 0
  438.         move.w    20(a3),d2    ;number of waveforms
  439.         lea    278(a3),a3    ;ptr to wf ptrs
  440.         subq.w    #1,d2
  441. relsyn        add.l    d3,(a3)+
  442.         dbf    d2,relsyn
  443. nosyn        dbf     d0,relocs
  444. xloci        rts
  445. norel        addq.l    #4,a0
  446.         rts
  447. relocentr    tst.l   (a0)
  448.         beq.s   norel
  449.         add.l   d1,(a0)+
  450.         rts
  451. _RelocModule    movem.l    a2-a3/d2-d3,-(sp)
  452.         move.l  a2,d1        ;d1 = ptr to start of module
  453.         bsr.s    relocp
  454.         movea.l 8(a2),a1
  455.         bsr.s    reloci
  456. rel_lp        bsr.s    relocb
  457.         move.l    32(a2),d0    ;extension struct
  458.         beq.s    rel_ex
  459.         move.l    d0,a0
  460.         bsr.s    relocentr    ;ptr to next module
  461.         bsr.s    relocentr    ;InstrExt...
  462.         addq.l    #4,a0        ;skip sizes of InstrExt
  463.         bsr.s    relocentr    ;annotxt
  464.         addq.l    #4,a0        ;annolen
  465.         bsr.s    relocentr    ;InstrInfo
  466.         addq.l    #8,a0
  467.         bsr.s    relocentr    ;rgbtable (not useful for most people)
  468.         addq.l    #4,a0        ;skip channelsplit
  469.         bsr.s    relocentr    ;NotationInfo
  470.         bsr.s    relocentr    ;songname
  471.         addq.l    #4,a0        ;skip song name length
  472.         bsr.s    relocentr    ;MIDI dumps
  473.         bsr.s    relocmdd
  474.         move.l    d0,a0
  475.         move.l    (a0),d0
  476.         beq.s    rel_ex
  477.         move.l    d0,a2
  478.         bsr.s    relocp
  479.         movea.l 8(a2),a1
  480.         bra.s    rel_lp
  481. rel_ex        movem.l    (sp)+,d2-d3/a2-a3
  482.         rts
  483. relocp        lea    8(a2),a0
  484.         bsr.s    relocentr
  485.         addq.l    #4,a0
  486.         bsr.s    relocentr
  487.         addq.l    #4,a0
  488.         bsr.s    relocentr
  489.         addq.l    #4,a0
  490.         bra.s    relocentr
  491. relocb        move.l    16(a2),d0
  492.         beq.s    xlocb
  493.         movea.l    d0,a0
  494.         move.w  504(a1),d0
  495.         subq.b  #1,d0
  496. rebl        bsr.s   relocentr
  497.         dbf     d0,rebl
  498.         cmp.b    #'1',3(a2)    ;test MMD type
  499.         beq.s    relocbi
  500. xlocb        rts
  501. relocmdd    tst.l    -(a0)
  502.         beq.s    xlocmdd
  503.         movea.l    (a0),a0
  504.         move.w    (a0),d0        ;# of msg dumps
  505.         addq.l    #8,a0
  506. mddloop        beq.s    xlocmdd
  507.         bsr    relocentr
  508.         bsr.s    relocdmp
  509.         subq.w    #1,d0
  510.         bra.s    mddloop
  511. xlocmdd        rts
  512. relocdmp    move.l    -4(a0),d3
  513.         beq.s    xlocdmp
  514.         exg.l    a0,d3        ;save
  515.         addq.l    #4,a0
  516.         bsr    relocentr    ;reloc data pointer
  517.         move.l    d3,a0        ;restore
  518. xlocdmp        rts
  519. relocbi        move.w    504(a1),d0
  520.         move.l    a0,a3
  521. biloop        subq.w    #1,d0
  522.         bmi.s    xlocdmp
  523.         move.l    -(a3),a0
  524.         addq.l    #4,a0
  525.         bsr    relocentr    ;BlockInfo ptr
  526.         tst.l    -(a0)
  527.         beq.s    biloop
  528.         move.l    (a0),a0
  529.         bsr    relocentr    ;hldata
  530.         bsr    relocentr    ;block name
  531.         bra.s    biloop
  532.     ENDC
  533.  
  534.  
  535. _ChannelOff:    ;d0 = channel #
  536.         lea    DB,a0
  537.         lea    trackdataptrs-DB(a0),a1
  538.         lsl.b    #2,d0
  539.         adda.w    d0,a1
  540.         lsr.b    #2,d0
  541.         movea.l    (a1),a1
  542.     IFNE    MIDI
  543.         move.b    trk_prevmidin(a1),d1    ;first: is it MIDI??
  544.         beq.s    notcomidi    ;not a midi note
  545.         lea    noteondata-DB(a0),a0
  546. choff_midi:    clr.b    trk_prevmidin(a1)
  547.         move.b    d1,1(a0)
  548.         bmi.s    notamigatrk
  549.         move.b    trk_prevmidich(a1),(a0)    ;prev midi channel
  550.         clr.b    2(a0)
  551.         or.b    #$90,(a0)        ;note off
  552.         moveq    #3,d0
  553.         bra.w    _AddMIDIData
  554.     ENDC
  555. notcomidi:    cmp.b    #4,d0
  556.         bge.s    notamigatrk
  557.     IFNE    SYNTH
  558.         clr.l    trk_synthptr(a1)
  559.         clr.b    trk_synthtype(a1)
  560.     ENDC
  561.         moveq    #1,d1
  562.         lsl.w    d0,d1
  563.         move.w    d1,$dff096
  564. notamigatrk:    rts
  565.  
  566. SoundOff:    move.l    d2,-(sp)
  567.         moveq    #15,d2
  568. SO_loop0    move.l    d2,d0
  569.         bsr.s    _ChannelOff
  570.         dbf    d2,SO_loop0
  571.         clr.l    _module        ;play nothing
  572.         move.l    (sp)+,d2
  573. SO_rts        rts
  574.  
  575. _PlayNote:    ;d7(w) = trk #, d1 = note #, d3(w) = instr # a3 = addr of instr
  576.         move.l    a3,d4
  577.         beq.s    SO_rts
  578.         moveq    #0,d4
  579.         bset    d7,d4    ;d4 is mask for this channel
  580.         movea.l    mmd_smplarr(a2),a0
  581.         add.w    d3,d3            ;d3 = instr.num << 2
  582.         add.w    d3,d3
  583.         move.l    0(a0,d3.w),d5        ;get address of instrument
  584.     IFNE    MIDI
  585.         bne.s    inmem
  586.         tst.b    inst_midich(a3)        ;is MIDI channel set
  587.     ENDC
  588.     IFNE    CHECK
  589.         beq.w    pnote_rts        ; NO!!!
  590.     ENDC
  591. inmem:        add.b    msng_playtransp(a4),d1    ;add play transpose
  592.         add.b    inst_strans(a3),d1    ;and instr. transpose
  593.         cmp.b    #4,d7
  594.         bge.s    nodmaoff    ;track # >= 4: not an Amiga channel
  595.         move.l    d5,a1
  596.     IFNE    SYNTH
  597.         tst.l    d5
  598.         beq.s    stpdma
  599.         tst.b    trk_synthtype(a5)
  600.         ble.s    stpdma        ;prev. type = sample/hybrid
  601.         cmp.w    #-1,4(a1)    ;type == SYNTHETIC??
  602.         beq.s    nostpdma
  603.     ENDC
  604. stpdma:        move.w    d4,$dff096        ;stop this channel (dmacon)
  605. nostpdma:
  606.     IFNE    SYNTH
  607.         clr.l    trk_synthptr(a5)
  608.     ENDC
  609. nodmaoff:    subq.b    #1,d1
  610.     IFNE    MIDI
  611.         move.b    trk_prevmidin(a5),d3    ;get prev. midi note
  612.         beq.s    noprevmidi
  613.         clr.b    trk_prevmidin(a5)
  614.         lea    noteondata+2-DB(a6),a0
  615.         clr.b    (a0)
  616.         move.b    d3,-(a0)
  617.         bmi.s    noprevmidi
  618.         move.b    trk_prevmidich(a5),-(a0) ;prev midi channel
  619.         or.b    #$90,(a0)         ;note off
  620.         move.w    d1,-(sp)
  621.         moveq    #3,d0
  622.         bsr.w    _AddMIDId
  623.         move.w    (sp)+,d1
  624. noprevmidi:
  625.         tst.b    inst_midich(a3)
  626.         bne.w    handleMIDInote
  627.     ENDC
  628.     IFNE    CHECK
  629.         cmp.w    #4,d7        ;track > 3???
  630.         bge.w    pnote_rts    ;no Amiga instruments here!!!
  631.     ENDC
  632. ; handle decay (for tracks 0 - 3 only!!)
  633.     IFNE    HOLD
  634.         clr.b    trk_fadespd(a5)        ;no fade yet..
  635.         move.b    trk_initdecay(a5),trk_decay(a5)    ;set decay
  636.     ENDC
  637.         clr.w    trk_vibroffs(a5)    ;clr vibrato/tremolo offset
  638.         or.w    d4,dmaonmsk-DB(a6)
  639.         move.l    d5,a0
  640.     IFNE    SYNTH
  641.         tst.w    4(a0)
  642.         bmi.w    handleSynthnote
  643.         clr.b    trk_synthtype(a5)
  644.     ENDC
  645. tlwtst0:    tst.b    d1
  646.         bpl.s    notenot2low
  647.         add.b    #12,d1    ;note was too low, octave up
  648.         bra.s    tlwtst0
  649. notenot2low:    cmp.b    #62,d1
  650.         ble.s    endpttest
  651.         sub.b    #12,d1    ;note was too high, octave down
  652. endpttest
  653.         moveq    #0,d2
  654.         moveq    #0,d3
  655.     IFNE    IFFMOCT
  656.         move.w    4(a0),d0    ;Soitin-struct in a0
  657.         bne.s    iff5or3oct    ;note # in d1 (0 - ...)
  658.     ENDC
  659.         lea    _periodtable+32-DB(a6),a1
  660.         move.b    trk_finetune(a5),d2    ;finetune value
  661.         add.b    d2,d2
  662.         add.b    d2,d2        ;multiply by 4...
  663.         ext.w    d2        ;extend
  664.         movea.l    0(a1,d2.w),a1    ;period table address
  665.         move.l    a1,trk_periodtbl(a5)
  666.         add.b    d1,d1
  667.         move.w    0(a1,d1.w),d5 ;put period to d5
  668.         move.l    a0,d0
  669.         addq.l    #6,d0        ;Skip structure
  670.         move.l    (a0),d1        ;length
  671.         add.l    d0,d1        ;sample end pointer
  672.         move.w    inst_repeat(a3),d2
  673.         move.w    inst_replen(a3),d3
  674.     IFNE    IFFMOCT
  675.         bra    gid_setrept
  676. gid_addtable    dc.b    0,6,12,18,24,30
  677. gid_divtable    dc.b    31,7,3,15,63,127
  678. iff5or3oct:    move.l    d7,-(sp)
  679.         moveq    #0,d7
  680.         move.w    d1,d7
  681.         divu    #12,d7    ;octave #
  682.         move.l    d7,d5
  683.         cmp.w    #6,d7    ;if oct > 5, oct = 5
  684.         blt.s    nohioct
  685.         moveq    #5,d7
  686. nohioct        swap    d5    ;note number in this oct (0-11) is in d5
  687.         move.l    (a0),d1
  688.         cmp.w    #6,d0
  689.         ble.s    nounrecit
  690.         moveq    #6,d0
  691. nounrecit    add.b    gid_addtable-1(pc,d0.w),d7
  692.         move.b    gid_divtable-1(pc,d0.w),d0
  693.         divu    d0,d1    ;get length of the highest octave
  694.         swap    d1
  695.         clr.w    d1
  696.         swap    d1
  697.         move.l    d1,d0        ;d0 and d1 = length of the 1st oct
  698.         move.w    inst_repeat(a3),d2
  699.         move.w    inst_replen(a3),d3
  700.         moveq    #0,d6
  701.         move.b    shiftcnt(pc,d7.w),d6
  702.         lsl.w    d6,d2
  703.         lsl.w    d6,d3
  704.         lsl.w    d6,d1
  705.         move.b    mullencnt(pc,d7.w),d6
  706.         mulu    d6,d0        ;offset of this oct from 1st oct
  707.         add.l    a0,d0        ;add base address to offset
  708.         addq.l    #6,d0        ;skip structure
  709.         add.l    d0,d1
  710.         lea    _periodtable+32-DB(a6),a1
  711.         move.b    trk_finetune(a5),d6
  712.         add.b    d6,d6
  713.         add.b    d6,d6
  714.         ext.w    d6
  715.         movea.l    0(a1,d6.w),a1
  716.         move.l    a1,trk_periodtbl(a5)
  717.         add.b    octstart(pc,d7.w),d5
  718.         add.b    d5,d5
  719.         move.w    0(a1,d5.w),d5
  720.         move.l    (sp)+,d7
  721.         bra.s    gid_setrept
  722. shiftcnt:    dc.b    4,3,2,1,1,0,2,2,1,1,0,0,1,1,0,0,0,0
  723.         dc.b    3,3,2,2,1,0,5,4,3,2,1,0,6,5,4,3,2,1
  724. mullencnt:    dc.b    15,7,3,1,1,0,3,3,1,1,0,0,1,1,0,0,0,0
  725.         dc.b    7,7,3,3,1,0,31,15,7,3,1,0,63,31,15,7,3,1
  726. octstart:    dc.b    12,12,12,12,24,24,0,12,12,24,24,36,0,12,12,24,36,36
  727.         dc.b    0,12,12,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12
  728.     ENDC
  729. gid_setrept    add.l    d2,d2
  730.         add.l    d0,d2        ;rep. start pointer
  731.         cmp.w    #1,d3
  732.         bhi.s    gid_noreplen2
  733.         moveq    #0,d3        ;no repeat
  734.         bra.s    gid_cont
  735. gid_noreplen2    add.l    d3,d3
  736.         add.l    d2,d3        ;rep. end pointer
  737.  
  738. gid_cont    moveq    #0,d4
  739.         move.w    trk_soffset(a5),d4
  740.         add.l    d4,d0
  741.         cmp.l    d0,d1
  742.         bhi.s    pn_nooffsovf
  743.         sub.l    d4,d0
  744. pn_nooffsovf    movea.l    trk_audioaddr(a5),a1 ;base of this channel's regs
  745.         move.l    d0,(a1)+        ;put it in ac_ptr
  746.         cmp.l    d0,d3
  747.         bhi.s    repeat
  748.         
  749.         move.l    #_chipzero,trk_sampleptr(a5) ;pointer of zero word
  750.         move.w    #1,trk_samplelen(a5)    ;length: 1 word
  751.         sub.l    d0,d1
  752.         lsr.l    #1,d1            ;shift length right
  753.         move.w    d1,(a1)+            ;and put to ac_len
  754.         bra.s    retsn1
  755.  
  756. repeat:        move.l    d2,trk_sampleptr(a5)
  757.         move.l    d3,d1
  758.         sub.l    d0,d1
  759.         lsr.l    #1,d1
  760.         move.w    d1,(a1)+    ;ac_len
  761.         sub.l    d2,d3
  762.         lsr.l    #1,d3
  763.         move.w    d3,trk_samplelen(a5)
  764.                 
  765. retsn1        move.w    d5,trk_prevper(a5)
  766.     IFNE    SYNTH
  767.         tst.b    trk_synthtype(a5)
  768.         bne.w    hSn2
  769.     ENDC
  770. pnote_rts    rts
  771.  
  772.     IFNE    MIDI
  773. handleMIDInote:
  774.     IFNE    PLAYMMD0
  775.         cmp.b    #'1',3(a2)
  776.         beq.s    plr_mmd1_3
  777.         add.b    #24,d1
  778. plr_mmd1_3
  779.     ENDC
  780.         move.b    trk_prevvol(a5),d2 ;temporarily save the volume
  781.         add.b    d2,d2        ;volume 0 - 63 => 0 - 127
  782.         subq.b    #1,d2        ;if 128 => 127
  783.         bpl.s    hmn_notvolu0
  784.         moveq    #0,d2
  785. hmn_notvolu0
  786.         moveq    #0,d5
  787.         move.b    inst_midich(a3),d5 ;get midi chan of this instrument
  788.         bpl.s    hmn_nosmof    ;bit 7 clear
  789.         clr.b    trk_prevmidin(a5)    ;suppress note off!
  790.         and.b    #$1F,d5        ;clear all flag bits etc...
  791.         bra.s    hmn_smof
  792. hmn_nosmof    move.b    d1,trk_prevmidin(a5)
  793. hmn_smof    subq.b    #1,d5        ;from 1-16 to 0-15
  794.         move.b    d5,trk_prevmidich(a5)    ;save to prev midi channel
  795.  
  796.         move.b    inst_midipreset(a3),d0    ;get preset #
  797.         beq.s    nochgpres    ;zero = no preset
  798.         lea    prevmidicpres-DB(a6),a1
  799.         adda.w    d5,a1
  800.         cmp.b    (a1),d0        ;is this previous preset ??
  801.         beq.s    nochgpres    ;yes...no need to change
  802.         move.b    d0,(a1)        ;save preset to prevmidicpres
  803.         subq.b    #1,d0        ;sub 1 to get 0 - 127
  804.         lea    preschgdata+1-DB(a6),a0
  805.         move.b    d0,(a0)        ;push the number to second byte
  806.         move.b    #$c0,-(a0)    ;command: $C
  807.         or.b    d5,(a0)        ;"or" midi channel
  808.         moveq    #2,d0
  809.         move.w    d1,-(sp)
  810.         bsr.w    _AddMIDId
  811.         move.w    (sp)+,d1
  812.         tst.b    d2
  813.         beq.s    hmn_suppress    ;vol = 0, don't send NOTE ON
  814.  
  815. nochgpres    lea    bytesinnotebuff-DB(a6),a0
  816.         movea.l    a0,a1
  817.         adda.w    (a0)+,a0
  818.         or.b    #$90,d5        ;MIDI: Note on
  819.         move.b    d5,(a0)+    ;MIDI msg Note on & channel
  820.         move.b    d1,(a0)+    ;MIDI msg note #
  821.         move.b    d2,(a0)        ;MIDI msg volume
  822.         beq.s    hmn_suppress    ;vol = 0 -> no note
  823.         addq.w    #3,(a1)
  824.         rts
  825. hmn_suppress    st    trk_prevmidin(a5)
  826.         rts
  827.     ENDC
  828.  
  829.     IFNE    SYNTH
  830. handleSynthnote:
  831.         move.b    d1,trk_prevnote2(a5)
  832.         move.l    a0,trk_synthptr(a5)
  833.         cmp.w    #-2,4(a0)    ;HYBRID??
  834.         bne.s    hSn_nossn
  835.         st    trk_synthtype(a5)
  836.         movea.l    278(a0),a0    ;yep, get the waveform pointer
  837.         bra.w    tlwtst0        ;go and play it
  838. hSn_nossn:    move.b    #1,trk_synthtype(a5)
  839.         lea    _periodtable+32-DB(a6),a1
  840.         move.b    trk_finetune(a5),d0    ;finetune value
  841.         add.b    d0,d0
  842.         add.b    d0,d0        ;multiple by 4...
  843.         ext.w    d0        ;extend
  844.         movea.l    0(a1,d0.w),a1    ;period table address
  845.         suba.w    #48,a1
  846.         move.l    a1,trk_periodtbl(a5) ;save table ptr for synth periods
  847.         add.w    d1,d1
  848.         move.w    0(a1,d1.w),d1
  849.         move.w    d1,trk_prevper(a5)
  850.         clr.l    trk_sampleptr(a5)
  851. hSn2:        lea    trk_arpgoffs(a5),a1
  852.         clr.l    (a1)+
  853.         clr.l    (a1)+
  854.         clr.l    (a1)+
  855.         clr.l    (a1)+
  856.         clr.l    (a1)+
  857.         clr.l    (a1)+
  858.         move.l    #sinetable,(a1)+
  859.         clr.w    (a1)+
  860.         movea.l    trk_synthptr(a5),a0
  861.                 move.w    18(a0),(a1)+
  862.                 clr.b    (a1)
  863.                 cmp.b    #$E,trk_cmd(a5)
  864.                 bne.s    hSn_nocmdE
  865.                 move.b    trk_cmdqual(a5),trk_wfcmd+1(a5)
  866. hSn_nocmdE    moveq    #64,d4
  867.         rts
  868.  
  869. synth_start    move.w    trk_prevper(a5),d5
  870. synth_start2    move.l    a3,-(sp)    ;d0 = SynthPtr
  871.         move.l    d0,a0
  872.         movea.l    trk_audioaddr(a5),a3    ;audio channel base address
  873.         subq.b    #1,trk_volxcnt(a5)    ;decrease execute counter..
  874.         bgt.w    synth_wftbl        ;not 0...go to waveform
  875.         move.b    trk_initvolxspd(a5),trk_volxcnt(a5) ;reset counter
  876.         move.b    trk_volchgspd(a5),d0    ;volume change??
  877.         beq.s    synth_nochgvol        ;no.
  878.         add.b    trk_synvol(a5),d0    ;add previous volume
  879.         bpl.s    synth_voln2l        ;not negative
  880.         moveq    #0,d0            ;was negative => 0
  881. synth_voln2l    cmp.b    #$40,d0            ;too high??
  882.         ble.s    synth_voln2h        ;not 2 high.
  883.         moveq    #$40,d0            ;was 2 high => 64
  884. synth_voln2h    move.b    d0,trk_synvol(a5)    ;remember new...
  885. synth_nochgvol    move.l    trk_envptr(a5),d1    ;envelope pointer
  886.         beq.s    synth_novolenv
  887.         movea.l    d1,a1
  888.         move.b    (a1)+,d0
  889.         add.b    #128,d0
  890.         lsr.b    #2,d0
  891.         move.b    d0,trk_synvol(a5)
  892.         addq.b    #1,trk_envcount(a5)
  893.         bpl.s    synth_endenv
  894.         clr.b    trk_envcount(a5)
  895.         move.l    trk_envrestart(a5),a1
  896. synth_endenv    move.l    a1,trk_envptr(a5)
  897. synth_novolenv    move.w    trk_volcmd(a5),d0    ;get table position ptr
  898.         tst.b    trk_volwait(a5)        ;WAI(t) active
  899.         beq.s    synth_getvolcmd        ;no
  900.         subq.b    #1,trk_volwait(a5)    ;yep, decr wait ctr
  901.         ble.s    synth_getvolcmd        ;0 => continue
  902.         bra.w    synth_wftbl        ;> 0 => still wait
  903. synth_inccnt    addq.b    #1,d0
  904. synth_getvolcmd    addq.b    #1,d0            ;advance pointer
  905.         move.b    21(a0,d0.w),d1        ;get command
  906.         bmi.s    synth_cmd        ;negative = command
  907.         move.b    d1,trk_synvol(a5)    ;set synthvol
  908.         bra.w    synth_endvol        ;end of volume executing
  909. synth_cmd    and.w    #$000f,d1
  910.         add.b    d1,d1
  911.         move.w    synth_vtbl(pc,d1.w),d1
  912.         jmp    syv(pc,d1.w)
  913. synth_vtbl    dc.w    syv_f0-syv,syv_f1-syv,syv_f2-syv,syv_f3-syv
  914.         dc.w    syv_f4-syv,syv_f5-syv,syv_f6-syv
  915.         dc.w    synth_endvol-syv,synth_endvol-syv,synth_endvol-syv
  916.         dc.w    syv_fa-syv,syv_ff-syv,synth_endvol-syv
  917.         dc.w    synth_endvol-syv,syv_fe-syv,syv_ff-syv
  918. syv
  919. syv_fe        move.b    22(a0,d0.w),d0        ;JMP
  920.         bra.s    synth_getvolcmd
  921. syv_f0        move.b    22(a0,d0.w),trk_initvolxspd(a5) ;change volume ex. speed
  922.         bra.s    synth_inccnt
  923. syv_f1        move.b    22(a0,d0.w),trk_volwait(a5)    ;WAI(t)
  924.         addq.b    #1,d0
  925.         bra.s    synth_endvol
  926. syv_f3        move.b    22(a0,d0.w),trk_volchgspd(a5) ;set volume slide up
  927.         bra.s    synth_inccnt
  928. syv_f2        move.b    22(a0,d0.w),d1
  929.         neg.b    d1
  930.         move.b    d1,trk_volchgspd(a5) ;set volume slide down
  931.         bra.s    synth_inccnt
  932. syv_fa        move.b    22(a0,d0.w),trk_wfcmd+1(a5) ;JWS (jump wform sequence)
  933.         clr.b    trk_wfwait(a5)
  934.         bra.s    synth_inccnt
  935. syv_f4        move.b    22(a0,d0.w),d1
  936.         bsr.s    synth_getwf
  937.         clr.l    trk_envrestart(a5)
  938. syv_f4end    move.l    a1,trk_envptr(a5)
  939.         clr.b    trk_envcount(a5)
  940.         bra.w    synth_inccnt
  941. syv_f5        move.b    22(a0,d0.w),d1
  942.         bsr.s    synth_getwf
  943.         move.l    a1,trk_envrestart(a5)
  944.         bra.s    syv_f4end
  945. syv_f6        clr.l    trk_envptr(a5)
  946.         bra.w    synth_getvolcmd
  947. synth_getwf    ext.w    d1    ;d1 = wform number, returns ptr in a1
  948.         add.w    d1,d1    ;create index
  949.         add.w    d1,d1
  950.         lea    278(a0),a1
  951.         adda.w    d1,a1
  952.         movea.l    (a1),a1        ;get wform address
  953.         addq.l    #2,a1        ;skip length
  954.         rts
  955. syv_ff        subq.b    #1,d0
  956. synth_endvol    move.w    d0,trk_volcmd(a5)
  957. synth_wftbl    move.b    trk_synvol(a5),trk_prevvol(a5)
  958.         adda.w    #158,a0
  959.         subq.b    #1,trk_wfxcnt(a5)    ;decr. wf speed counter
  960.         bgt.w    synth_arpeggio        ;not yet...
  961.         move.b    trk_initwfxspd(a5),trk_wfxcnt(a5) ;restore speed counter
  962.         move.w    trk_wfcmd(a5),d0    ;get table pos offset
  963.         move.w    trk_wfchgspd(a5),d1    ;CHU/CHD ??
  964.         beq.s    synth_tstwfwai        ;0 = no change
  965. wytanwet    add.w    trk_perchg(a5),d1    ;add value to current change
  966.         move.w    d1,trk_perchg(a5)    ;remember amount of change
  967. synth_tstwfwai    tst.b    trk_wfwait(a5)        ;WAI ??
  968.         beq.s    synth_getwfcmd        ;not waiting...
  969.         subq.b    #1,trk_wfwait(a5)    ;decr wait counter
  970.         beq.s    synth_getwfcmd        ;waiting finished
  971.         bra.w    synth_arpeggio        ;still sleep...
  972. synth_incwfc    addq.b    #1,d0
  973. synth_getwfcmd    addq.b    #1,d0            ;advance position counter
  974.         move.b    -9(a0,d0.w),d1        ;get command
  975.         bmi.s    synth_wfcmd        ;negative = command
  976.         ext.w    d1
  977.         add.w    d1,d1
  978.         add.w    d1,d1
  979.         movea.l    120(a0,d1.w),a1
  980.         move.w    (a1)+,ac_len(a3)    ;push waveform length
  981.         move.l    a1,ac_ptr(a3)        ;and the new pointer
  982.         bra.w    synth_wfend        ;no new commands now...
  983. synth_wfcmd    and.w    #$000f,d1        ;get the right nibble
  984.         add.b    d1,d1            ;* 2
  985.         move.w    synth_wfctbl(pc,d1.w),d1
  986.         jmp    syw(pc,d1.w)        ;jump to command
  987. synth_wfctbl    dc.w    syw_f0-syw,syw_f1-syw,syw_f2-syw,syw_f3-syw,syw_f4-syw
  988.         dc.w    syw_f5-syw,syw_f6-syw,syw_f7-syw,synth_wfend-syw
  989.         dc.w    synth_wfend-syw,syw_fa-syw,syw_ff-syw
  990.         dc.w    syw_fc-syw,synth_getwfcmd-syw,syw_fe-syw,syw_ff-syw
  991. syw
  992. syw_f7        move.b    -8(a0,d0.w),d1
  993.         ext.w    d1
  994.         add.w    d1,d1
  995.         add.w    d1,d1
  996.         movea.l    120(a0,d1.w),a1
  997.         addq.l    #2,a1
  998.         move.l    a1,trk_synvibwf(a5)
  999.         bra.s    synth_incwfc
  1000. syw_fe        move.b    -8(a0,d0.w),d0        ;jump (JMP)
  1001.         bra.s    synth_getwfcmd
  1002. syw_fc        move.w    d0,trk_arpsoffs(a5)    ;new arpeggio begin
  1003.         move.w    d0,trk_arpgoffs(a5)
  1004. synth_findare    addq.b    #1,d0
  1005.         tst.b    -9(a0,d0.w)
  1006.         bpl.s    synth_findare
  1007.         bra.s    synth_getwfcmd
  1008. syw_f0        move.b    -8(a0,d0.w),trk_initwfxspd(a5)    ;new waveform speed
  1009.         bra    synth_incwfc
  1010. syw_f1        move.b    -8(a0,d0.w),trk_wfwait(a5)    ;wait waveform
  1011.         addq.b    #1,d0
  1012.         bra.s    synth_wfend
  1013. syw_f4        move.b    -8(a0,d0.w),trk_synvibdep+1(a5)    ;set vibrato depth
  1014.         bra.w    synth_incwfc
  1015. syw_f5        move.b    -8(a0,d0.w),trk_synthvibspd+1(a5) ;set vibrato speed
  1016.         addq.b    #1,trk_synthvibspd+1(a5)
  1017.         bra.w    synth_incwfc
  1018. syw_f2        moveq    #0,d1            ;set slide down
  1019.         move.b    -8(a0,d0.w),d1
  1020. synth_setsld    move.w    d1,trk_wfchgspd(a5)
  1021.         bra.w    synth_incwfc
  1022. syw_f3        move.b    -8(a0,d0.w),d1        ;set slide up
  1023.         neg.b    d1
  1024.         ext.w    d1
  1025.         bra.s    synth_setsld
  1026. syw_f6        clr.w    trk_perchg(a5)        ;reset period
  1027.         move.w    trk_prevper(a5),d5
  1028.         bra.w    synth_getwfcmd
  1029. syw_fa        move.b    -8(a0,d0.w),trk_volcmd+1(a5) ;JVS (jump volume sequence)
  1030.         clr.b    trk_volwait(a5)
  1031.         bra.w    synth_incwfc
  1032. syw_ff        subq.b    #1,d0        ;pointer = END - 1
  1033. synth_wfend    move.w    d0,trk_wfcmd(a5)
  1034. synth_arpeggio    move.w    trk_arpgoffs(a5),d0
  1035.         beq.s    synth_vibrato
  1036.         moveq    #0,d1
  1037.         move.b    -8(a0,d0.w),d1
  1038.         add.b    trk_prevnote2(a5),d1
  1039.         movea.l    trk_periodtbl(a5),a1    ;get period table
  1040.         add.w    d1,d1
  1041.         move.w    0(a1,d1.w),d5
  1042.         addq.b    #1,d0
  1043.         tst.b    -8(a0,d0.w)
  1044.         bpl.s    synth_noarpres
  1045.         move.w    trk_arpsoffs(a5),d0
  1046. synth_noarpres    move.w    d0,trk_arpgoffs(a5)
  1047. synth_vibrato    move.w    trk_synvibdep(a5),d1    ;get vibrato depth
  1048.         beq.s    synth_rts        ;0 => no vibrato
  1049.         move.w    trk_synviboffs(a5),d0    ;get offset
  1050.         lsr.w    #4,d0            ;/ 16
  1051.         and.w    #$1f,d0            ;sinetable offset (0-31)
  1052.         movea.l trk_synvibwf(a5),a0
  1053.         move.b    0(a0,d0.w),d0       ;get a byte
  1054.         ext.w    d0            ;to word
  1055.         muls    d1,d0            ;amplify (* depth)
  1056.         asr.w    #8,d0            ;and divide by 64
  1057.         add.w    d0,d5            ;add vibrato...
  1058.         move.w    trk_synthvibspd(a5),d0    ;vibrato speed
  1059.         add.w    d0,trk_synviboffs(a5)    ;add to offset
  1060. synth_rts    add.w    trk_perchg(a5),d5
  1061.         cmp.w    #113,d5            ;overflow??
  1062.         bge.s    synth_pern2h
  1063.         moveq    #113,d1
  1064. synth_pern2h    move.l    (sp)+,a3
  1065.         rts
  1066.     ENDC
  1067. sinetable    dc.b    0,25,49,71,90,106,117,125,127,125,117,106,90,71,49
  1068.         dc.b    25,0,-25,-49,-71,-90,-106,-117,-125,-127,-125,-117
  1069.         dc.b    -106,-90,-71,-49,-25,0
  1070.  
  1071. _IntHandler:    movem.l    d2-d7/a2-a6,-(sp)
  1072.         movea.l    a1,a6        ;get data base address
  1073.         tst.b    bpmcounter-DB(a6)
  1074.         bmi.s    plr_nobpm
  1075.         subq.b    #1,bpmcounter-DB(a6)
  1076.         ble.s    plr_bpmcnt0
  1077.         bra.w    plr_exit
  1078. plr_bpmcnt0    move.b    #4,bpmcounter-DB(a6)
  1079. plr_nobpm    movea.l    _module-DB(a6),a2
  1080.         move.l    a2,d0
  1081.         beq.w    plr_exit
  1082.     IFNE    MIDI
  1083.         clr.b    lastcmdbyte-DB(a6)    ;no MIDI optimization
  1084.     ENDC
  1085.         tst.w    mmd_pstate(a2)
  1086.         beq.w    plr_exit
  1087.     IFNE    MIDI
  1088.         clr.l    dmaonmsk-DB(a6)
  1089.     ENDC
  1090.     IFEQ    MIDI
  1091.         clr.w    dmaonmsk-DB(a6)
  1092.     ENDC
  1093.         movea.l    mmd_songinfo(a2),a4
  1094.         moveq    #0,d3
  1095.         move.b    mmd_counter(a2),d3
  1096.         addq.b    #1,d3
  1097.         cmp.b    msng_tempo2(a4),d3
  1098.         bge.s    plr_pnewnote    ;play new note
  1099.         move.b    d3,mmd_counter(a2)
  1100.         bne.w    plr_fxtime    ;do just fx
  1101. ; --- new note!!
  1102. plr_pnewnote:    clr.b    mmd_counter(a2)
  1103.         tst.w    blkdelay-DB(a6)
  1104.         beq.s    plr_noblkdelay
  1105.         subq.w    #1,blkdelay-DB(a6)
  1106.         bne.w    nonewnote
  1107. ; --- now start to play it
  1108. plr_noblkdelay    move.w    mmd_pblock(a2),d0
  1109.         movea.l    mmd_blockarr(a2),a0
  1110.         add.w    d0,d0
  1111.         add.w    d0,d0
  1112.         movea.l    0(a0,d0.w),a1    ;block...
  1113.         move.w    mmd_pline(a2),d0
  1114.     IFNE    PLAYMMD0
  1115.         cmp.b    #'1',3(a2)    ;check ID type
  1116.         beq.s    plr_mmd1_0
  1117.         move.w    d0,d1
  1118.         add.w    d0,d0
  1119.         add.w    d1,d0        ;d0 = d0 * 3
  1120.         clr.l    numtracks-DB(a6)
  1121.         move.b    (a1)+,numtracks+1-DB(a6)
  1122.         move.b    (a1),numlines+1-DB(a6)
  1123.         mulu    numtracks-DB(a6),d0
  1124.         pea    1(a1,d0.w)
  1125.         bra.s    plr_begloop
  1126. plr_mmd1_0
  1127.     ENDC
  1128.         add.w    d0,d0
  1129.         add.w    d0,d0        ;d0 = d0 * 4
  1130.         mulu    (a1),d0        ;numtracks * d0
  1131.         pea    8(a1,d0.l)    ;address of the current note
  1132.         move.w    (a1)+,numtracks-DB(a6)
  1133.         move.w    (a1),numlines-DB(a6)
  1134. plr_begloop    moveq    #0,d7        ;number of track
  1135.         moveq    #0,d4
  1136.         pea    trackdataptrs-DB(a6)
  1137. plr_loop0:    moveq    #0,d5
  1138.         move.l    (sp),a1
  1139.         movea.l    (a1)+,a5    ;get address of this track's struct
  1140.         move.l    a1,(sp)
  1141. ; ---------------- get the note numbers
  1142.         moveq    #0,d3
  1143.         move.l    4(sp),a1
  1144.     IFNE    PLAYMMD0
  1145.         cmp.b    #'1',3(a2)
  1146.         beq.s    plr_mmd1_1
  1147.         move.b    (a1)+,d5
  1148.         move.b    (a1)+,d6
  1149.         move.b    (a1)+,trk_cmdqual(a5)
  1150.         move.b    d6,d3
  1151.         and.w    #$0F,d6
  1152.         lsr.b    #4,d3
  1153.         bclr    #7,d5
  1154.         beq.s    plr_bseti4
  1155.         bset    #4,d3
  1156. plr_bseti4    bclr    #6,d5
  1157.         beq.s    plr_bseti5
  1158.         bset    #5,d3
  1159. plr_bseti5    bra.s    plr_nngok
  1160. plr_mmd1_1
  1161.     ENDC
  1162.         move.b    (a1)+,d5    ;get the number of this note
  1163.         bpl.s    plr_nothinote
  1164.         moveq    #0,d5
  1165. plr_nothinote    move.b    (a1)+,d3    ;instrument number
  1166.         move.b    (a1)+,d6    ;cmd number
  1167.         and.w    #$1F,d6        ;recognize only cmds 00 - 1F
  1168.         move.b    (a1)+,trk_cmdqual(a5)    ;databyte (qualifier)
  1169. plr_nngok    move.l    a1,4(sp)
  1170. ; ---------------- check if there's an instrument number
  1171.         and.w    #$3F,d3
  1172.         beq.s    noinstnum
  1173. ; ---------------- finally, save the number
  1174.         subq.b    #1,d3
  1175.         move.b    d3,trk_previnstr(a5) ;remember instr. number!
  1176.     IFNE    HOLD
  1177.         lea    holdvals-DB(a6),a0
  1178.         adda.w    d3,a0
  1179.         move.b    (a0),trk_inithold(a5)
  1180.         move.b    63(a0),trk_initdecay(a5)
  1181.         move.b    126(a0),trk_finetune(a5)
  1182.     ENDC
  1183.         asl.w    #3,d3
  1184.         lea    0(a4,d3.w),a3    ;a3 contains now address of it
  1185.         move.l    a3,trk_previnstra(a5)
  1186.         moveq    #0,d0
  1187. ; ---------------- get volume and make it relative (1 - 100 %)
  1188.     IFNE    RELVOL
  1189.         move.b    inst_svol(a3),d0
  1190.         mulu    trk_trackvol(a5),d0
  1191.         lsr.w    #8,d0
  1192.         move.b    d0,trk_prevvol(a5) ;vol of this instr
  1193.     ENDC
  1194.     IFEQ    RELVOL
  1195.         move.b    inst_svol(a3),trk_prevvol(a5)
  1196.     ENDC
  1197. ; ---------------- remember transpose
  1198.         move.b    inst_strans(a3),trk_stransp(a5)
  1199.         clr.w    trk_soffset(a5)        ;sample offset
  1200. ; ---------------- check the commands
  1201. noinstnum    move.b    d6,trk_cmd(a5)    ;save the effect number
  1202.         beq.w    fx    ;no effect
  1203.         move.b    trk_cmdqual(a5),d4    ;get qualifier...
  1204.         add.b    d6,d6    ;* 2
  1205.         move.w    f_table(pc,d6.w),d0
  1206.         jmp    fst(pc,d0.w)
  1207. f_table        dc.w    fx-fst,fx-fst,fx-fst,f_03-fst,fx-fst,fx-fst,fx-fst,fx-fst
  1208.         dc.w    f_08-fst,f_09-fst,fx-fst,f_0b-fst,f_0c-fst,fx-fst,f_0e-fst,f_0f-fst
  1209.         dc.w    fx-fst,fx-fst,fx-fst,fx-fst,fx-fst,f_15-fst,f_16-fst,fx-fst
  1210.         dc.w    fx-fst,f_19-fst,fx-fst,fx-fst,f_1c-fst,f_1d-fst,fx-fst,f_1f-fst
  1211. fst
  1212. ; ---------------- tempo (F)
  1213. f_0f        tst.b    d4        ;test effect qual..
  1214.         beq    fx0fchgblck    ;if effect qualifier (last 2 #'s)..
  1215.         cmp.b    #$f0,d4        ;..is zero, go to next block
  1216.         bhi.s    fx0fspecial    ;if it's F1-FF something special
  1217. ; ---------------- just an ordinary "change tempo"-request
  1218.     IFNE    CIAB
  1219.         moveq    #0,d0        ;will happen!!!
  1220.         move.b    d4,d0
  1221.         move.w    d0,msng_deftempo(a4)
  1222.         bsr    _SetTempo    ;change The Tempo
  1223.     ENDC
  1224.         bra.w    fx
  1225. ; ---------------- no, it was FFx, something special will happen!!
  1226. fx0fspecial:    cmp.b    #$f2,d4
  1227.         bne.s    isfxfe
  1228. ; ---------------- FF2 (or 1Fxx)
  1229. f_1f        move.b    d5,(a5)    ; save the note number
  1230.         moveq    #0,d5    ; clear the number for awhile
  1231.     IFNE    HOLD
  1232.         move.b    trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  1233.         bne.w    plr_endloop0        ;not 0 -> OK
  1234.         st    trk_noteoffcnt(a5)    ;0 -> hold = 0xff (-1)
  1235.     ENDC
  1236.         bra.w    plr_endloop0
  1237. isfxfe:        cmp.b    #$fe,d4
  1238.         bne.s    notcmdfe
  1239. ; ---------------- it was FFE, stop playing
  1240.         clr.w    mmd_pstate(a2)
  1241.     IFNE    CIAB
  1242.         movea.l    craddr-DB(a6),a0
  1243.         bclr    #0,(a0)
  1244.     ENDC
  1245.         bsr.w    SoundOff
  1246.         addq.l    #8,sp
  1247.         bra.w    plr_exit
  1248. notcmdfe:    cmp.b    #$fd,d4 ;change period
  1249.         bne.s    isfxff
  1250. ; ---------------- FFD, change the period, don't replay the note
  1251.     IFNE    CHECK
  1252.         cmp.w    #4,d7
  1253.         bge.w    fx
  1254.     ENDC
  1255.         movea.l    trk_periodtbl(a5),a0
  1256.         subq.b    #1,d5
  1257.         bmi.w    plr_endloop0
  1258.         add.b    d5,d5
  1259.         move.w    0(a0,d5.w),trk_prevper(a5)
  1260.         moveq    #0,d5
  1261.         bra.w    fx
  1262. isfxff:        cmp.b    #$ff,d4
  1263.         bne.w    fx
  1264.         move.w    d7,d0
  1265.         bsr.w    _ChannelOff
  1266.         bra.w    fx
  1267. ; ---------------- F00, called Pattern Break in ST
  1268. fx0fchgblck:    move.b    #1,nextblock-DB(a6)
  1269.         bra.w    fx
  1270. ; ---------------- was not Fxx
  1271. f_0e        cmp.b    #3,d7
  1272.         bgt.w    fx
  1273.         move.b    d4,trk_wfcmd+1(a5) ;set waveform command position ptr
  1274.         bra.w    fx
  1275. ; ---------------- change volume
  1276. f_0c        move.b    d4,d0
  1277.         bpl.s    plr_nosetdefvol
  1278.         and.b    #$7F,d0
  1279.     IFNE    CHECK
  1280.         cmp.b    #64,d0
  1281.         bgt.s    go_nocmd
  1282.     ENDC
  1283.         moveq    #0,d1
  1284.         move.b    trk_previnstr(a5),d1
  1285.         asl.w    #3,d1
  1286.         move.b    d0,inst_svol(a4,d1.w)
  1287.         bra.s    plr_setvol
  1288. plr_nosetdefvol    btst    #4,msng_flags(a4)    ;look at flags
  1289.         bne.s    volhex
  1290.         lsr.b    #4,d0        ;get number from left
  1291.         mulu    #10,d0        ;number of tens
  1292.         move.b    d4,d1        ;get again
  1293.         and.b    #$0f,d1        ;this time don't get tens
  1294.         add.b    d1,d0        ;add them
  1295. volhex:
  1296.     IFNE    CHECK
  1297.         cmp.b    #64,d0
  1298.         bhi.s    go_nocmd
  1299.     ENDC
  1300. plr_setvol
  1301.     IFNE    RELVOL
  1302.         mulu    trk_trackvol(a5),d0
  1303.         lsr.w    #8,d0
  1304.     ENDC
  1305.         move.b    d0,trk_prevvol(a5)
  1306. go_nocmd    bra.w    fx
  1307. ; ---------------- tempo2 change??
  1308. f_09
  1309.     IFNE    CHECK
  1310.         and.b    #$1F,d4
  1311.         bne.s    fx9chk
  1312.         moveq    #$20,d4
  1313.     ENDC
  1314. fx9chk:        move.b    d4,msng_tempo2(a4)
  1315.         bra    fx
  1316. ; ---------------- finetune
  1317. f_15
  1318.     IFNE    CHECK
  1319.         cmp.b    #7,d4
  1320.         bgt    fx
  1321.         cmp.b    #-8,d4
  1322.         blt    fx
  1323.     ENDC
  1324.         move.b    d4,trk_finetune(a5)
  1325.         bra    fx
  1326. ; ---------------- repeat loop
  1327. f_16        tst.b    d4
  1328.         bne.s    plr_dorpt
  1329.         move.w    mmd_pline(a2),rptline-DB(a6)
  1330.         bra    fx
  1331. plr_dorpt    tst.w    rptcounter-DB(a6)
  1332.         beq.s    plr_newrpt
  1333.         subq.w    #1,rptcounter-DB(a6)
  1334.         beq    fx
  1335.         bra.s    plr_setrptline
  1336. plr_newrpt    move.b    d4,rptcounter+1-DB(a6)
  1337. plr_setrptline    move.w    rptline-DB(a6),d0
  1338.         addq.w    #1,d0
  1339.         move.w    d0,nextblockline-DB(a6)
  1340.         bra    fx
  1341. ; ---------------- preset change
  1342. f_1c
  1343.     IFNE    CHECK
  1344.         cmp.b    #$80,d4
  1345.         bhi    fx
  1346.     ENDC
  1347.         moveq    #0,d1
  1348.         move.b    trk_previnstr(a5),d1
  1349.         asl.w    #3,d1
  1350.         move.b    d4,inst_midipreset(a4,d1.w)    ;set MIDI preset
  1351.         bra.s    fx
  1352. ; ---------------- note off time set??
  1353. f_08
  1354.     IFNE    HOLD
  1355.         move.b    d4,d0
  1356.         lsr.b    #4,d4        ;extract left  nibble
  1357.         and.b    #$0f,d0        ; "   "  right  "  "
  1358.         move.b    d4,trk_initdecay(a5)    ;left = decay
  1359.         move.b    d0,trk_inithold(a5)    ;right = hold
  1360.     ENDC
  1361.         bra.s    fx
  1362. ; ---------------- sample begin offset
  1363. f_19        lsl.w    #8,d4
  1364.         move.w    d4,trk_soffset(a5)
  1365.         bra.s    fx
  1366. ; ---------------- cmd Bxx, "position jump"
  1367. f_0b
  1368.     IFNE    CHECK
  1369.         cmp.w    msng_songlen(a4),d4
  1370.         bhi.s    fx
  1371.     ENDC
  1372.         move.w    d4,mmd_pseqnum(a2)
  1373.         st    nextblock-DB(a6)    ; = 1
  1374.         bra.s    fx
  1375. ; ---------------- cmd 1Dxx, jump to next seq, line # specified
  1376. f_1d        move.w    #$1ff,nextblock-DB(a6)
  1377.         addq.w    #1,d4
  1378.         move.w    d4,nextblockline-DB(a6)
  1379.         bra.s    fx
  1380. ; ---------------- try portamento (3)
  1381. f_03
  1382.     IFNE    CHECK
  1383.         cmp.w    #4,d7
  1384.         bge.s    plr_endloop0
  1385.     ENDC
  1386.         subq.b    #1,d5        ;subtract note number
  1387.         bmi.s    plr_setfx3spd    ;0 -> set new speed
  1388. plr_fx3note:    movea.l    trk_periodtbl(a5),a0
  1389.         add.b    msng_playtransp(a4),d5    ;play transpose
  1390.         add.b    trk_stransp(a5),d5    ;and instrument transpose
  1391.         bmi.s    plr_endloop0
  1392.         add.w    d5,d5
  1393.         move.w    0(a0,d5.w),trk_porttrgper(a5) ;period of this note is the target
  1394. plr_setfx3spd:    tst.b    d4        ;qual??
  1395.         beq.s    plr_endloop0    ;0 -> do nothing
  1396.         move.b    d4,trk_prevportspd(a5)    ;store speed
  1397.         bra.s    plr_endloop0        ;don't play this one
  1398. ; ---------------- play or not to play??
  1399. fx        tst.b    d5            ;play a note?
  1400.         beq.s    plr_endloop0        ;no.
  1401. ; ---------------- play
  1402.         move.b    d5,(a5)
  1403.         move.w    d5,d1
  1404.         moveq    #0,d3
  1405.         move.b    trk_previnstr(a5),d3    ;instr #
  1406.         movea.l    trk_previnstra(a5),a3    ;instr data address
  1407.     IFNE    HOLD
  1408.         move.b    trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  1409.         bne.s    plr_nohold0        ;not 0 -> OK
  1410.         st    trk_noteoffcnt(a5)    ;0 -> hold = 0xff (-1)
  1411.     ENDC
  1412. ; ---------------- and finally:
  1413. plr_nohold0    bsr    _PlayNote
  1414. ; ---------------- end of loop: handle next track, or quit
  1415. plr_endloop0:    addq.b    #1,d7
  1416.         cmp.w    numtracks-DB(a6),d7
  1417.         blt.w    plr_loop0
  1418.         addq.l    #8,sp            ;trackdataptrs / note ptr
  1419. ; and advance song pointers
  1420.         lea    nextblock-DB(a6),a3
  1421.         move.w    nextblockline-DB(a6),d1
  1422.         beq.s    plr_advlinenum
  1423.         clr.w    nextblockline-DB(a6)
  1424.         subq.w    #1,d1
  1425.         bra.s    plr_linenumset
  1426. plr_advlinenum    move.w    mmd_pline(a2),d1    ;get current line #
  1427.         addq.w    #1,d1            ;advance line number
  1428. plr_linenumset    cmp.w    numlines-DB(a6),d1     ;advance block?
  1429.         bhi.s    plr_chgblock        ;yes.
  1430.         tst.b    (a3)            ;command F00/1Dxx?
  1431.         beq.s    plr_nochgblock        ;no, don't change block
  1432. plr_chgblock    tst.b    nxtnoclrln-DB(a6)
  1433.         bne.s    plr_noclrln
  1434.         moveq    #0,d1            ;clear line number
  1435. plr_noclrln    tst.w    mmd_pstate(a2)        ;play block or play song
  1436.         bpl.s    plr_nonewseq        ;play block only...
  1437.         move.w    mmd_pseqnum(a2),d0    ;get play sequence number
  1438.         tst.b    (a3)
  1439.         bmi.s    plr_noadvseq        ;Bxx sets nextblock to -1
  1440.         addq.w    #1,d0            ;advance sequence number
  1441. plr_noadvseq    cmp.w    msng_songlen(a4),d0    ;is this the highest seq number??
  1442.         blt.s    plr_notagain        ;no.
  1443.         moveq    #0,d0            ;yes: restart song
  1444. plr_notagain    move.b    d0,mmd_pseqnum+1(a2)    ;remember new playseq-#
  1445.         lea    msng_playseq(a4),a0    ;offset of sequence table
  1446.         move.b    0(a0,d0.w),d0        ;get number of the block
  1447.     IFNE    CHECK
  1448.         cmp.w    msng_numblocks(a4),d0    ;beyond last block??
  1449.         blt.s    plr_nolstblk        ;no..
  1450.         moveq    #0,d0            ;play block 0
  1451.     ENDC
  1452. plr_nolstblk    move.b    d0,mmd_pblock+1(a2)    ;store block number
  1453. plr_nonewseq    clr.w    (a3)             ;clear this if F00 set it
  1454. plr_nochgblock    move.w    d1,mmd_pline(a2)    ;set new line number
  1455.  
  1456.     IFNE    HOLD
  1457.         lea    trackdataptrs-DB(a6),a5
  1458.         movea.l    mmd_blockarr(a2),a0
  1459.         move.w    mmd_pblock(a2),d0
  1460.         add.w    d0,d0
  1461.         add.w    d0,d0
  1462.         movea.l    0(a0,d0.w),a1    ;block...
  1463.         move.w    mmd_pline(a2),d0
  1464.         move.b    msng_tempo2(a4),d3    ;interrupts/note
  1465.     IFNE    PLAYMMD0
  1466.         cmp.b    #'1',3(a2)
  1467.         beq.s    plr_mmd1_2
  1468.         move.b    (a1),d7            ;# of tracks
  1469.         move.w    d0,d1
  1470.         add.w    d0,d0    ;d0 * 2
  1471.         add.w    d1,d0    ;+ d0 = d0 * 3
  1472.         mulu    d7,d0
  1473.         lea    2(a1,d0.w),a3
  1474.         subq.b    #1,d7
  1475. plr_chkholdb    movea.l    (a5)+,a1        ;track data
  1476.         tst.b    trk_noteoffcnt(a1)    ;hold??
  1477.         bmi.s    plr_holdendb        ;no.
  1478.         move.b    (a3),d1            ;get the 1st byte..
  1479.         bne.s    plr_hold1b
  1480.         move.b    1(a3),d1
  1481.         and.b    #$f0,d1
  1482.         beq.s    plr_holdendb        ;don't hold
  1483.         bra.s    plr_hold2b
  1484. plr_hold1b    and.b    #$3f,d1            ;note??
  1485.         beq.s    plr_hold2b        ;no, cont hold..
  1486.         move.b    1(a3),d1
  1487.         and.b    #$0f,d1            ;get cmd
  1488.         subq.b    #3,d1            ;is there command 3 (slide)
  1489.         bne.s    plr_holdendb        ;no -> end holding
  1490. plr_hold2b    add.b    d3,trk_noteoffcnt(a1)    ;continue holding...
  1491. plr_holdendb    addq.l    #3,a3        ;next note
  1492.         dbf    d7,plr_chkholdb
  1493.         bra.s    nonewnote
  1494. plr_mmd1_2
  1495.     ENDC
  1496.         move.w    (a1),d7        ;# of tracks
  1497.         add.w    d0,d0
  1498.         add.w    d0,d0    ;d0 = d0 * 4
  1499.         mulu    d7,d0
  1500.         lea    8(a1,d0.l),a3
  1501.         subq.b    #1,d7
  1502. plr_chkhold    movea.l    (a5)+,a1        ;track data
  1503.         tst.b    trk_noteoffcnt(a1)    ;hold??
  1504.         bmi.s    plr_holdend        ;no.
  1505.         move.b    (a3),d1            ;get the 1st byte..
  1506.         bne.s    plr_hold1
  1507.         move.b    1(a3),d0
  1508.         and.b    #$3F,d0
  1509.         beq.s    plr_holdend        ;don't hold
  1510.         bra.s    plr_hold2
  1511. plr_hold1    and.b    #$7f,d1            ;note??
  1512.         beq.s    plr_hold2        ;no, cont hold..
  1513.         move.b    2(a3),d1
  1514.         subq.b    #3,d1            ;is there command 3 (slide)
  1515.         bne.s    plr_holdend        ;no -> end holding
  1516. plr_hold2    add.b    d3,trk_noteoffcnt(a1)    ;continue holding...
  1517. plr_holdend    addq.l    #4,a3        ;next note
  1518.         dbf    d7,plr_chkhold
  1519.     ENDC    
  1520. nonewnote    moveq    #0,d3
  1521.         move.b    mmd_counter(a2),d3
  1522. plr_fxtime    lea    trackdataptrs-DB(a6),a3
  1523.         moveq    #0,d7    ;clear track count
  1524. plr_loop1    movea.l    (a3)+,a5
  1525.         moveq    #0,d4
  1526.         moveq    #0,d5
  1527.         moveq    #0,d6
  1528.         move.b    trk_cmd(a5),d6    ;get the fx number
  1529.         move.b    trk_cmdqual(a5),d4    ;and the last 2 #'s
  1530.     IFNE    MIDI
  1531.         tst.b    trk_prevmidin(a5)    ;is it MIDI??
  1532.         bne.w    midicmds
  1533.     ENDC
  1534.         cmp.w    #4,d7
  1535.     IFNE    MIDI
  1536.         bge.w    midicmds    ;no non-MIDI effects in tracks 4 - 15
  1537.     ENDC
  1538.     IFEQ    MIDI
  1539.         bge.w    endl
  1540.     ENDC
  1541.     IFNE    HOLD
  1542.         tst.b    trk_noteoffcnt(a5)
  1543.         bmi.s    plr_nowaitoff
  1544.         subq.b    #1,trk_noteoffcnt(a5)
  1545.         bpl.s    plr_nowaitoff
  1546.     IFNE    SYNTH
  1547.         tst.b    trk_synthtype(a5)        ;synth/hybrid??
  1548.         beq.s    plr_nosyndec
  1549.         move.b    trk_decay(a5),trk_volcmd+1(a5)    ;set volume command pointer
  1550.         clr.b    trk_volwait(a5)            ;abort WAI
  1551.         bra.s    plr_nowaitoff
  1552.     ENDC
  1553. plr_nosyndec:    move.b    trk_decay(a5),trk_fadespd(a5)    ;set fade...
  1554.         bne.s    plr_nowaitoff            ;if > 0, don't stop sound
  1555.         bset    d7,d5
  1556.         move.w    d5,$dff096            ;shut DMA...
  1557.         moveq    #0,d5
  1558.     ENDC
  1559. plr_nowaitoff:    
  1560.     IFNE    HOLD
  1561.         move.b    trk_fadespd(a5),d0    ;fade??
  1562.         beq.s    plr_nofade    ;no.
  1563.         sub.b    d0,trk_prevvol(a5)
  1564.         bpl.s    plr_nofade
  1565.         clr.b    trk_prevvol(a5)
  1566.         clr.b    trk_fadespd(a5)        ;fade no more
  1567.     ENDC
  1568. plr_nofade    add.b    d6,d6    ;* 2
  1569.         move.w    fx_table(pc,d6.w),d0
  1570.         jmp    fxs(pc,d0.w)
  1571. fx_table    dc.w    fx_00-fxs,fx_01-fxs,fx_02-fxs,fx_03-fxs,fx_04-fxs
  1572.         dc.w    fx_05-fxs,fx_06-fxs,fx_07-fxs,fx_xx-fxs,fx_xx-fxs
  1573.         dc.w    fx_0a-fxs,fx_xx-fxs,fx_xx-fxs,fx_0d-fxs,fx_xx-fxs
  1574.         dc.w    fx_0f-fxs
  1575.         dc.w    fx_10-fxs,fx_11-fxs,fx_12-fxs,fx_13-fxs,fx_14-fxs
  1576.         dc.w    fx_xx-fxs,fx_xx-fxs,fx_xx-fxs,fx_18-fxs,fx_xx-fxs
  1577.         dc.w    fx_1a-fxs,fx_1b-fxs,fx_xx-fxs,fx_xx-fxs,fx_1e-fxs
  1578.         dc.w    fx_1f-fxs
  1579. fxs:
  1580. ;    **************************************** Effect 01 ******
  1581. fx_01:        tst.b    d3
  1582.         bne.s    fx_01nocnt0
  1583.         btst    #5,msng_flags(a4)    ;FLAG_STSLIDE??
  1584.         bne    fx_xx
  1585. fx_01nocnt0    sub.w    d4,trk_prevper(a5)
  1586.         move.w    trk_prevper(a5),d5
  1587.         cmp.w    #113,d5
  1588.         bge    plr_newper
  1589.         move.w    #113,d5
  1590.         move.w    d5,trk_prevper(a5)
  1591.         bra    plr_newper
  1592. ;    **************************************** Effect 11 ******
  1593. fx_11        tst.b    d3
  1594.         bne    fx_xx
  1595.         sub.w    d4,trk_prevper(a5)
  1596.         move.w    trk_prevper(a5),d5
  1597.         bra    plr_newper
  1598. ;    **************************************** Effect 02 ******
  1599. fx_02:        tst.b    d3
  1600.         bne.s    fx_02nocnt0
  1601.         btst    #5,msng_flags(a4)
  1602.         bne    fx_xx
  1603. fx_02nocnt0    add.w    d4,trk_prevper(a5)
  1604.         move.w    trk_prevper(a5),d5
  1605.         bra.w    plr_newper
  1606. ;    **************************************** Effect 12 ******
  1607. fx_12        tst.b    d3
  1608.         bne    fx_xx
  1609.         add.w    d4,trk_prevper(a5)
  1610.         move.w    trk_prevper(a5),d5
  1611.         bra    plr_newper
  1612. ;    **************************************** Effect 00 ******
  1613. fx_00:        tst.b    d4    ;both fxqualifiers are 0s: no arpeggio
  1614.         beq.w    fx_xx
  1615.         move.l    d3,d0
  1616.         divu    #3,d0
  1617.         swap    d0
  1618.         tst.w    d0
  1619.         bne.s    fx_arp12
  1620.         and.b    #$0f,d4
  1621.         add.b    (a5),d4
  1622.         bra.s    fx_doarp
  1623. fx_arp12:    subq.b    #1,d0
  1624.         bne.s    fx_arp2
  1625.         lsr.b    #4,d4
  1626.         add.b    (a5),d4
  1627.         bra.s    fx_doarp
  1628. fx_arp2:    move.b    (a5),d4
  1629. fx_doarp:    subq.b    #1,d4        ;-1 to make it 0 - 127
  1630.         add.b    msng_playtransp(a4),d4    ;add play transpose
  1631.         add.b    trk_stransp(a5),d4    ;add instrument transpose
  1632.         add.b    d4,d4
  1633.         movea.l    trk_periodtbl(a5),a1
  1634.         move.w    0(a1,d4.w),d5
  1635.         bra.w    plr_newtmp
  1636. ;    **************************************** Effect 04 ******
  1637. fx_14        move.b    #6,trk_vibshift(a5)
  1638.         bra.s    vib_cont
  1639. fx_04        move.b    #5,trk_vibshift(a5)
  1640. vib_cont    tst.b    d3
  1641.         bne.s    nonvib
  1642.         move.b    d4,d1
  1643.         beq.s    nonvib
  1644.         and.w    #$0f,d1
  1645.         beq.s    plr_chgvibspd
  1646.         move.w    d1,trk_vibrsz(a5)
  1647. plr_chgvibspd:    and.b    #$f0,d4
  1648.         beq.s    nonvib
  1649.         lsr.b    #3,d4
  1650.         and.b    #$3e,d4
  1651.         move.b    d4,trk_vibrspd(a5)
  1652. nonvib:        move.b    trk_vibroffs(a5),d0
  1653.         lsr.b    #2,d0
  1654.         and.w    #$1f,d0
  1655.         moveq    #0,d1
  1656.         lea    sinetable(pc),a0
  1657.         move.b    0(a0,d0.w),d5
  1658.         ext.w    d5
  1659.         muls    trk_vibrsz(a5),d5
  1660.         move.b    trk_vibshift(a5),d1
  1661.         asr.w    d1,d5
  1662.         add.w    trk_prevper(a5),d5
  1663.         move.b    trk_vibrspd(a5),d0
  1664.         add.b    d0,trk_vibroffs(a5)
  1665.         bra.w    plr_newtmp
  1666. ;    **************************************** Effect 06 ******
  1667. fx_06:        tst.b    d3
  1668.         bne.s    fx_06nocnt0
  1669.         btst    #5,msng_flags(a4)
  1670.         bne    fx_xx
  1671. fx_06nocnt0    bsr.s    plr_volslide        ;Volume slide
  1672.         bra.s    nonvib            ;+ Vibrato
  1673. ;    **************************************** Effect 07 ******
  1674. fx_07        tst.b    d3
  1675.         bne.s    nontre
  1676.         move.b    d4,d1
  1677.         beq.s    nontre
  1678.         and.w    #$0f,d1
  1679.         beq.s    plr_chgtrespd
  1680.         move.w    d1,trk_tremsz(a5)
  1681. plr_chgtrespd    and.b    #$f0,d4
  1682.         beq.s    nonvib
  1683.         lsr.b    #2,d4
  1684.         and.b    #$3e,d4
  1685.         move.b    d4,trk_tremspd(a5)
  1686. nontre        move.b    trk_tremoffs(a5),d0
  1687.         lsr.b    #3,d0
  1688.         and.w    #$1f,d0
  1689.         moveq    #0,d1
  1690.         lea    sinetable(pc),a0
  1691.         move.b    0(a0,d0.w),d5
  1692.         ext.w    d5
  1693.         muls    trk_tremsz(a5),d5
  1694.         asr.w    #7,d5
  1695.         move.b    trk_tremspd(a5),d0
  1696.         add.b    d0,trk_tremoffs(a5)
  1697.         move.b    trk_prevvol(a5),d1
  1698.         add.b    d5,d1
  1699.         bpl.s    tre_pos
  1700.         moveq    #0,d1
  1701. tre_pos        cmp.b    #64,d1
  1702.         ble.s    tre_no2hi
  1703.         moveq    #64,d1
  1704. tre_no2hi    move.b    d1,trk_tempvol(a5)
  1705.         bra.w    fx_xx
  1706. ;    **************************************** Effect 0D/0A ***
  1707. fx_0a:
  1708. fx_0d:        tst.b    d3
  1709.         bne.s    fx_0dnocnt0
  1710.         btst    #5,msng_flags(a4)
  1711.         bne    fx_xx
  1712. fx_0dnocnt0    bsr.s    plr_volslide
  1713.         bra    fx_xx
  1714. ;    ********* VOLUME SLIDE FUNCTION *************************
  1715. plr_volslide    move.b    d4,d0
  1716.         moveq    #0,d1
  1717.         move.b    trk_prevvol(a5),d1 ;move previous vol to d1
  1718.         and.b    #$f0,d0
  1719.         bne.s    crescendo
  1720.         sub.b    d4,d1    ;sub from prev. vol
  1721. voltest0    bpl.s    novolover64
  1722.         moveq    #0,d1    ;volumes under zero not accepted!!!
  1723.         bra.s    novolover64
  1724. crescendo:    lsr.b    #4,d0
  1725.         add.b    d0,d1
  1726. voltest        cmp.b    #64,d1
  1727.         ble.s    novolover64
  1728.         moveq    #64,d1
  1729. novolover64    move.b    d1,trk_prevvol(a5)
  1730.         rts
  1731. ;    **************************************** Effect 1A ******
  1732. fx_1a        tst.b    d3
  1733.         bne    fx_xx
  1734.         move.b    trk_prevvol(a5),d1
  1735.         add.b    d4,d1
  1736.         bsr.s    voltest
  1737.         bra    fx_xx
  1738. ;    **************************************** Effect 1B ******
  1739. fx_1b        tst.b    d3
  1740.         bne    fx_xx
  1741.         move.b    trk_prevvol(a5),d1
  1742.         sub.b    d4,d1
  1743.         bsr.s    voltest0
  1744.         bra    fx_xx
  1745. ;    **************************************** Effect 05 ******
  1746. fx_05:        tst.b    d3
  1747.         bne.s    fx_05nocnt0
  1748.         btst    #5,msng_flags(a4)
  1749.         bne    fx_xx
  1750. fx_05nocnt0    bsr.s    plr_volslide        ;Volume slide
  1751.         bra.s    fx_03nocnt0
  1752. ;    **************************************** Effect 03 ******
  1753. fx_03:        tst.b    d3
  1754.         bne.s    fx_03nocnt0
  1755.         btst    #5,msng_flags(a4)
  1756.         bne    fx_xx
  1757. fx_03nocnt0    move.w    trk_porttrgper(a5),d0    ;d0 = target period
  1758.         beq.w    fx_xx    ;no target period specified
  1759.         move.w    trk_prevper(a5),d1    ;d1 = curr. period
  1760.         move.b    trk_prevportspd(a5),d4    ;get prev. speed
  1761.         cmp.w    d0,d1
  1762.         bhi.s    subper    ;curr. period > target period
  1763.         add.w    d4,d1    ;add the period
  1764.         cmp.w    d0,d1
  1765.         bge.s    targreached
  1766.         bra.s    targnreach
  1767. subper:        sub.w    d4,d1    ;subtract
  1768.         cmp.w    d0,d1    ;compare current period to target period
  1769.         bgt.s    targnreach
  1770. targreached:    move.w    trk_porttrgper(a5),d1 ;eventually push target period
  1771.         clr.w    trk_porttrgper(a5) ;now we can forget everything
  1772. targnreach:    move.w    d1,trk_prevper(a5)
  1773.         move.w    d1,d5
  1774.         bra.s    plr_newper
  1775. ;    **************************************** Effect 13 ******
  1776. fx_13:        move.w    trk_prevper(a5),d5 ;this is very simple: get the old period
  1777.         cmp.b    #3,d3        ;and..
  1778.         bge.s    plr_newper    ;if counter < 3
  1779.         sub.w    d4,d5    ;subtract effect qualifier
  1780.         bra.s    plr_newper
  1781. ;    **************************************** Effect 10 ******
  1782. fx_10:
  1783.     IFNE    MIDI
  1784.         tst.b    d3
  1785.         bne.s    fx_xx
  1786.         move.w    d4,d0
  1787.         bsr.w    _InitMIDIDump
  1788.     ENDC
  1789.         bra.s    fx_xx
  1790. ;    **************************************** Effect 1E ******
  1791. fx_1e        tst.w    blkdelay-DB(a6)
  1792.         bne.s    fx_xx
  1793.         addq.w    #1,d4
  1794.         move.w    d4,blkdelay-DB(a6)
  1795.         bra.s    fx_xx
  1796. ;    **************************************** Effect 18 ******
  1797. fx_18        cmp.b    d4,d3
  1798.         bne.s    fx_xx
  1799.         clr.b    trk_prevvol(a5)
  1800.         bra.s    fx_xx
  1801. ;    **************************************** Effect 1F ******
  1802. fx_1f        move.b    d4,d1
  1803.         lsr.b    #4,d4        ;note delay
  1804.         beq.s    nonotedelay
  1805.         cmp.b    d4,d3        ;compare to counter
  1806.         blt.s    fx_xx        ;tick not reached
  1807.         bne.s    nonotedelay
  1808.         bsr    playfxnote    ;trigger note
  1809. nonotedelay    and.w    #$0f,d1        ;retrig?
  1810.         beq.s    fx_xx
  1811.         moveq    #0,d0
  1812.         move.b    d3,d0
  1813.         divu    d1,d0
  1814.         swap    d0        ;get modulo of counter/tick
  1815.         tst.w    d0
  1816.         bne.s    fx_xx
  1817.         bsr    playfxnote    ;retrigger
  1818.         bra.s    fx_xx
  1819. ;    **************************************** Effect 0F ******
  1820. fx_0f        bsr    cmd_F
  1821. ;    *********************************************************
  1822. plr_newper
  1823. fx_xx
  1824.     IFNE    SYNTH
  1825.         move.l    trk_synthptr(a5),d0
  1826.         beq.s    plr_nosynth
  1827.         bsr.w    synth_start
  1828.         bra.s    plr_tmpper
  1829. plr_newtmp    move.l    trk_synthptr(a5),d0
  1830.         beq.s    plr_tmpper
  1831.         bsr.w    synth_start2
  1832.         bra.s    plr_tmpper
  1833.     ENDC
  1834. plr_nosynth    move.w    trk_prevper(a5),d5
  1835.     IFEQ    SYNTH
  1836. plr_newtmp
  1837.     ENDC
  1838. plr_tmpper    movea.l    trk_audioaddr(a5),a1    ;get channel address
  1839.         move.w    d5,ac_per(a1)        ;push period
  1840.         beq.s    endl
  1841.         move.b    trk_tempvol(a5),d0
  1842.         bmi.s    plr_notmpvol
  1843.         jsr    CalcVol
  1844.         move.w    d0,ac_vol(a1)
  1845.         st    trk_tempvol(a5)
  1846.         bra.s    endl
  1847. plr_notmpvol    move.b    trk_prevvol(a5),d0
  1848.         jsr    CalcVol
  1849.         move.w    d0,ac_vol(a1)    ;get volume & push it
  1850. endl:        addq.b    #1,d7    ;increment channel number
  1851.         cmp.w    numtracks-DB(a6),d7    ;all channels done???
  1852.         blt.w    plr_loop1    ;not yet!!!
  1853. plr_endfx:    ;turn on DMA
  1854.         move.w    dmaonmsk-DB(a6),d0    ;dmaonmsk contains the mask of
  1855.     IFNE    MIDI
  1856.         beq.s    sdma_nodmaon    ;the channels that must be turned on
  1857.     ENDC
  1858.     IFEQ    MIDI
  1859.         beq.s    plr_exit
  1860.     ENDC    
  1861.         bset    #15,d0    ;DMAF_SETCLR: set these bits in dmacon
  1862.         moveq    #80,d1
  1863. ; The following line makes the playroutine one scanline slower. If your
  1864. ; song works well without the following instruction, you can leave it out.
  1865.     IFNE    SYNTH
  1866.         add.w    d1,d1    ;sometimes double wait time is required
  1867.     ENDC
  1868.         bsr.s    _Wait1line
  1869.         move.w    d0,$dff096    ;do that!!!
  1870.         moveq    #80,d1
  1871.         bsr.s    _Wait1line
  1872.         lea    trackdataptrs-DB(a6),a1
  1873.         bsr.s    pushnewvals
  1874.         bsr.s    pushnewvals
  1875.         bsr.s    pushnewvals
  1876.         bsr.s    pushnewvals
  1877.     IFNE    MIDI
  1878. sdma_nodmaon    lea    bytesinnotebuff-DB(a6),a0
  1879.         move.w    (a0)+,d0
  1880.         beq.s    plr_exit
  1881.         bsr.w    _AddMIDId
  1882.     ENDC
  1883. plr_exit:    movem.l    (sp)+,d2-d7/a2-a6
  1884.         moveq    #1,d0
  1885.         rts
  1886.  
  1887. _Wait1line:    move.w    d0,-(sp)    ;d1 = vsync counters to wait - 1
  1888. wl0:        move.b    $dff007,d0
  1889. wl1:        cmp.b    $dff007,d0
  1890.         beq.s    wl1
  1891.         dbf    d1,wl0
  1892.         move.w    (sp)+,d0
  1893.         rts
  1894. pushnewvals:    movea.l    (a1)+,a5
  1895.         lsr.b    #1,d0
  1896.         bcc.s    rpnewv
  1897.         move.l    trk_sampleptr(a5),d1
  1898.         beq.s    rpnewv
  1899.         movea.l    trk_audioaddr(a5),a0
  1900.         move.l    d1,ac_ptr(a0)
  1901.         move.w    trk_samplelen(a5),ac_len(a0)
  1902. rpnewv:        rts
  1903.  
  1904. cmd_F        cmp.b    #$f1,d4
  1905.         bne.s    no0ff1
  1906.         cmp.b    #3,d3
  1907.         beq.s    playfxnote
  1908.         rts
  1909. no0ff1:        cmp.b    #$f2,d4
  1910.         bne.s    no0ff2
  1911.         cmp.b    #3,d3
  1912.         beq.s    playfxnote
  1913.         rts
  1914. no0ff2:        cmp.b    #$f3,d4
  1915.         bne.s    no0ff3
  1916.         move.b    d3,d0
  1917.         and.b    #2+4,d0        ;is 2 or 4
  1918.         beq.s    cF_rts
  1919. playfxnote:    moveq    #0,d1
  1920.         move.b    (a5),d1        ;get note # of previous note
  1921.         beq.s    cF_rts
  1922.         move.b    trk_noteoffcnt(a5),d0    ;get hold counter
  1923.         bmi.s    pfxn_nohold        ;no hold, or hold over
  1924.         add.b    d3,d0            ;increase by counter val
  1925.         bra.s    pfxn_hold
  1926. pfxn_nohold    move.b    trk_inithold(a5),d0    ;get initial hold
  1927.         bne.s    pfxn_hold
  1928.         st    d0
  1929. pfxn_hold    move.b    d0,trk_noteoffcnt(a5)
  1930.         movem.l    d3/a3,-(sp)
  1931.         moveq    #0,d3
  1932.         move.b    trk_previnstr(a5),d3    ;and prev. sample #
  1933.         movea.l    trk_previnstra(a5),a3
  1934.         bsr    _PlayNote
  1935.         movem.l    (sp)+,d3/a3
  1936.         rts
  1937. no0ff3:        cmp.b    #$f8,d4        ;f8 = filter off
  1938.         beq.s    plr_filteroff
  1939.         cmp.b    #$f9,d4        ;f9 = filter on
  1940.         bne.s    cF_rts
  1941.         bclr    #1,$bfe001
  1942.         rts
  1943. plr_filteroff:    bset    #1,$bfe001
  1944. cF_rts        rts
  1945.  
  1946. _SetTempo:
  1947.     IFNE    CIAB
  1948.         move.l    _module-DB(a6),d1
  1949.         beq.s    ST_x
  1950.         move.l    d1,a0
  1951.         movea.l    mmd_songinfo(a0),a0
  1952.         btst    #5,msng_flags2(a0)
  1953.         bne.s    ST_bpm
  1954.         cmp.w    #10,d0    ;If tempo <= 10, use SoundTracker tempo
  1955.         bhi.s    calctempo
  1956.         subq.b    #1,d0
  1957.         add.w    d0,d0
  1958.         move.w    sttempo+2(pc,d0.w),d1
  1959.         bra.s    pushtempo
  1960. calctempo:    move.l    timerdiv-DB(a6),d1
  1961.         divu    d0,d1
  1962. pushtempo:    movea.l    craddr+4-DB(a6),a0
  1963.         move.b    d1,(a0)        ;and set the CIA timer
  1964.         lsr.w    #8,d1
  1965.         movea.l    craddr+8-DB(a6),a0
  1966.         move.b    d1,(a0)
  1967.     ENDC
  1968. ST_x        rts ;   vv-- These values are the SoundTracker tempos (approx.)
  1969. sttempo:    dc.w    $0f00
  1970.     IFNE    CIAB
  1971.         dc.w    2417,4833,7250,9666,12083,14500,16916,19332,21436,24163
  1972. ST_bpm        move.b    msng_flags2(a0),d1
  1973.         and.w    #$1F,d1
  1974.         addq.b    #1,d1
  1975.         mulu    d1,d0
  1976.         move.l    bpmdiv-DB(a6),d1
  1977.         divu    d0,d1
  1978.         bra.s    pushtempo
  1979.     ENDC
  1980.  
  1981.     IFNE    MIDI
  1982. midicmds
  1983.     IFNE    HOLD
  1984.         tst.b    trk_noteoffcnt(a5)
  1985.         bmi.s    midi_nowaitoff
  1986.         subq.b    #1,trk_noteoffcnt(a5)
  1987.         bpl.s    midi_nowaitoff
  1988.         move.l    a5,a1
  1989.         move.b    trk_prevmidin(a5),d1
  1990.         beq.s    midi_nowaitoff    ;no note
  1991.         lea    noteondata-DB(a6),a0
  1992.         bsr.w    choff_midi
  1993. midi_nowaitoff:
  1994.     ENDC
  1995.         add.b    d6,d6    ;* 2
  1996.         move.w    midicmd_table(pc,d6.w),d0
  1997.         jmp    midifx(pc,d0.w)
  1998. midicmd_table:    dc.w    mfx_00-midifx,mfx_01-midifx,mfx_02-midifx,mfx_03-midifx,mfx_04-midifx
  1999.         dc.w    mfx_05-midifx,endl-midifx,endl-midifx,endl-midifx,endl-midifx
  2000.         dc.w    mfx_0a-midifx,endl-midifx,endl-midifx,mfx_0d-midifx,mfx_0e-midifx
  2001.         dc.w    mfx_0f-midifx
  2002.         dc.w    mfx_10-midifx,endl-midifx,endl-midifx,endl-midifx
  2003.         dc.w    endl-midifx,endl-midifx,endl-midifx,mfx_17-midifx
  2004.         dc.w    endl-midifx,endl-midifx,endl-midifx,endl-midifx
  2005.         dc.w    endl-midifx,endl-midifx,endl-midifx,mfx_1f-midifx
  2006. midifx        
  2007. mfx_01        lea    prevmidipbend-DB(a6),a0
  2008.         moveq    #0,d1
  2009.         move.b    trk_prevmidich(a5),d1    ;get previous midi channel
  2010.         add.b    d1,d1        ;UWORD index
  2011.         tst.b    d4        ;x100??
  2012.         beq.s    resetpbend
  2013.         move.w    0(a0,d1.w),d0    ;get previous pitch bend
  2014.         lsl.w    #3,d4        ;multiply bend value by 8
  2015.         add.w    d4,d0
  2016.         cmp.w    #$3fff,d0
  2017.         bls.s    bendpitch
  2018.         move.w    #$3fff,d0
  2019. bendpitch:    move.w    d0,0(a0,d1.w)    ;save current pitch bend
  2020.         lsr.b    #1,d1        ;back to UBYTE
  2021.         or.b    #$e0,d1
  2022.         lea    noteondata-DB(a6),a0
  2023.         move.b    d1,(a0)        ;midi command & channel
  2024.         move.b    d0,1(a0)    ;lower value
  2025.         and.b    #$7f,1(a0)    ;clear bit 7
  2026.         lsr.w    #7,d0
  2027.         and.b    #$7f,d0        ;clr bit 7
  2028.         move.b    d0,2(a0)    ;higher 7 bits
  2029.         moveq    #3,d0
  2030.         bsr.w    _AddMIDId
  2031.         bra.w    endl
  2032.  
  2033. mfx_02        lea    prevmidipbend-DB(a6),a0
  2034.         moveq    #0,d1
  2035.         move.b    trk_prevmidich(a5),d1
  2036.         add.b    d1,d1
  2037.         tst.b    d4
  2038.         beq.s    resetpbend    ;x200??
  2039.         move.w    0(a0,d1.w),d0
  2040.         lsl.w    #3,d4
  2041.         sub.w    d4,d0
  2042.         bpl.s    bendpitch    ;not under 0
  2043.         moveq    #0,d0
  2044.         bra.s    bendpitch
  2045. resetpbend:    tst.b    d3        ;d3 = counter (remember??)
  2046.         bne.w    endl
  2047.         move.w    #$2000,d0
  2048.         bra.s    bendpitch
  2049.  
  2050. mfx_03        tst.b    d3
  2051.         bne.w    endl
  2052.         lea    prevmidipbend-DB(a6),a0
  2053.         moveq    #0,d1
  2054.         move.b    trk_prevmidich(a5),d1
  2055.         add.b    d1,d1
  2056.         move.b    d4,d0
  2057.         add.b    #128,d0
  2058.         lsl.w    #6,d0
  2059.         bra.s    bendpitch
  2060.  
  2061. mfx_0d        tst.b    d3
  2062.         bne.w    endl
  2063.         lea    noteondata+1-DB(a6),a0    ;CHANNEL AFTERTOUCH
  2064.         move.b    d4,(a0)    ;value
  2065.         bmi.w    endl
  2066.         move.b    trk_prevmidich(a5),-(a0)
  2067.         or.b    #$d0,(a0)
  2068.         moveq    #2,d0
  2069.         bsr.w    _AddMIDId
  2070.         bra.w    endl
  2071.  
  2072. mfx_0a        tst.b    d3
  2073.         bne.w    endl
  2074.         lea    noteondata+2-DB(a6),a0    ;POLYPHONIC AFTERTOUCH
  2075.         and.b    #$7f,d4
  2076.         move.b    d4,(a0)
  2077.         move.b    trk_prevmidin(a5),-(a0)
  2078.         ble.w    endl
  2079.         move.b    trk_prevmidich(a5),-(a0)
  2080.         or.b    #$A0,(a0)
  2081.         moveq    #3,d0
  2082.         bsr.w    _AddMIDId
  2083.         bra.w    endl
  2084.  
  2085. mfx_17        moveq    #$07,d0        ;07 = VOLUME
  2086.         bra.s    pushctrldata
  2087.  
  2088. mfx_04        moveq    #$01,d0        ;01 = MODULATION WHEEL
  2089.         bra.s    pushctrldata
  2090.  
  2091. mfx_0e        moveq    #$0a,d0
  2092. pushctrldata    tst.b    d3        ;do it only once in a note
  2093.         bne.w    endl        ;(when counter = 0)
  2094.         lea    noteondata+2-DB(a6),a0 ;push "control change" data,
  2095.         move.b    d4,(a0)        ;second databyte
  2096.         bmi.w    endl        ;$0 - $7F only
  2097.         move.b    d0,-(a0)    ;1st databyte
  2098.         move.b    trk_prevmidich(a5),-(a0)    ;MIDI channel
  2099.         or.b    #$b0,(a0)    ;command (B)
  2100.         moveq    #3,d0
  2101.         bsr.w    _AddMIDId
  2102.         bra.w    endl
  2103.  
  2104. mfx_05        and.b    #$7f,d4        ;set contr. value of curr. MIDI ch.
  2105.         move.b    trk_prevmidich(a5),d6
  2106.         lea    midicontrnum-DB(a6),a0
  2107.         adda.w    d6,a0
  2108.         move.b    d4,(a0)
  2109.         bra.w    endl
  2110.  
  2111. mfx_0f        cmp.b    #$fa,d4        ;hold pedal ON
  2112.         bne.s    nomffa
  2113.         moveq    #$40,d0
  2114.         moveq    #$7f,d4
  2115.         bra.s    pushctrldata
  2116. nomffa        cmp.b    #$fb,d4        ;hold pedal OFF
  2117.         bne.s    mfx_0f_2
  2118.         moveq    #$40,d0
  2119.         moveq    #$00,d4
  2120.         bra.s    pushctrldata
  2121. mfx_0f_2    bsr.w    cmd_F
  2122.         bra.w    endl
  2123.  
  2124. mfx_00        tst.b    d4
  2125.         beq.w    endl
  2126.         and.b    #$7f,d4
  2127.         move.b    trk_prevmidich(a5),d6
  2128.         lea    midicontrnum-DB(a6),a0
  2129.         move.b    0(a0,d6.w),d0
  2130.         bra.s    pushctrldata
  2131.  
  2132. mfx_10        tst.b    d3
  2133.         bne.w    endl
  2134.         move.w    d4,d0
  2135.         bsr.w    _InitMIDIDump
  2136.         bra.w    endl
  2137.  
  2138. mfx_1f        move.b    d4,d1
  2139.         lsr.b    #4,d4        ;note delay
  2140.         beq.s    nonotedelay_m
  2141.         cmp.b    d4,d3        ;compare to counter
  2142.         blt    endl        ;tick not reached
  2143.         bne.s    nonotedelay_m
  2144.         bsr    playfxnote    ;trigger note
  2145. nonotedelay_m    and.w    #$0f,d1        ;retrig?
  2146.         beq    endl
  2147.         moveq    #0,d0
  2148.         move.b    d3,d0
  2149.         divu    d1,d0
  2150.         swap    d0        ;get modulo of counter/tick
  2151.         tst.w    d0
  2152.         bne    endl
  2153.         bsr    playfxnote    ;retrigger
  2154.         bra    endl
  2155.  
  2156. _ResetMIDI:    movem.l    d2/a2/a6,-(sp)
  2157.         movea.l    4,a6        ;ExecBase
  2158.         jsr    -$78(a6)    ;Disable()
  2159.         lea    DB,a6
  2160. ; Clear preset memory
  2161.         lea    prevmidicpres-DB(a6),a0
  2162.         clr.l    (a0)+    ;force presets to be set again
  2163.         clr.l    (a0)+    ;(clear prev. preset numbers)
  2164.         clr.l    (a0)+
  2165.         clr.l    (a0)
  2166.         clr.b    lastcmdbyte
  2167. ; Reset pitchbenders & modulation wheels
  2168.         lea    midiresd-DB(a6),a2
  2169.         move.b    #$e0,(a2)
  2170.         move.b    #$b0,3(a2)
  2171.         moveq    #15,d2
  2172. respbendl:    movea.l    a2,a0
  2173.         moveq    #6,d0
  2174.         bsr.w    _AddMIDId
  2175.         addq.b    #1,(a2)
  2176.         addq.b    #1,3(a2)
  2177.         dbf    d2,respbendl
  2178.         lea    prevmidipbend-DB(a6),a2
  2179.         moveq    #15,d2
  2180. resprevpbends:    move.w    #$2000,(a2)+
  2181.         dbf    d2,resprevpbends
  2182. ; Clear dump variables
  2183.         clr.b    sysx-DB(a6)
  2184.         lea    dumpqueue-DB(a6),a0
  2185.         move.l    a0,dqreadptr-DB(a6)
  2186.         move.l    a0,dqwriteptr-DB(a6)
  2187.         clr.w    dqentries-DB(a6)
  2188. ; Enable & exit
  2189.         movea.l    4,a6
  2190.         jsr    -$7e(a6)    ;Enable()
  2191.         movem.l    (sp)+,d2/a2/a6
  2192.         rts
  2193.     ENDC
  2194.  
  2195. ; *************************************************************************
  2196. ; *************************************************************************
  2197. ; ***********          P U B L I C   F U N C T I O N S          ***********
  2198. ; *************************************************************************
  2199. ; *************************************************************************
  2200.  
  2201.     IFEQ    EASY
  2202.         XDEF    _InitModule,_PlayModule
  2203.         XDEF    _InitPlayer,_RemPlayer,_StopPlayer
  2204.         XDEF    _ContModule
  2205.     ENDC
  2206.  
  2207. ; *************************************************************************
  2208. ; InitModule(a0 = module) -- extract expansion data etc.. from V3.xx module
  2209. ; *************************************************************************
  2210.  
  2211. _InitModule:    movem.l    a2-a3/d2,-(sp)
  2212.         move.l    a0,d0
  2213.         beq    IM_exit            ;0 => xit
  2214.     IFNE    RELVOL
  2215.         movea.l    mmd_songinfo(a0),a1    ;MMD0song
  2216.         move.b    msng_mastervol(a1),d0    ;d0 = mastervol
  2217.         ext.w    d0
  2218.         lea    msng_trkvol(a1),a1    ;a1 = trkvol
  2219.         lea    trackdataptrs,a2
  2220.         moveq    #15,d1
  2221. IM_loop0    move.b    (a1)+,d2    ;get vol...
  2222.         ext.w    d2
  2223.         move.l    (a2)+,a3    ;pointer to track data
  2224.         mulu    d0,d2        ;mastervol * trackvol
  2225.         lsr.w    #4,d2
  2226.         move.w    d2,trk_trackvol(a3)
  2227.         dbf    d1,IM_loop0
  2228.     ENDC
  2229.         lea    holdvals,a2
  2230.         movea.l    a0,a3
  2231.         move.l    mmd_expdata(a0),d0    ;expdata...
  2232.         beq.s    IM_clrhlddec        ;none here
  2233.         move.l    d0,a1
  2234.         move.l    4(a1),d0        ;exp_smp
  2235.         beq.s    IM_clrhlddec    ;again.. nothing
  2236.         move.l    d0,a0        ;InstrExt...
  2237.         move.w    8(a1),d2    ;# of entries
  2238.         beq.s    IM_clrhlddec
  2239.         subq.w    #1,d2        ;- 1 (for dbf)
  2240.         move.w    10(a1),d0    ;entry size
  2241.     IFNE    MIDI
  2242.         movea.l    mmd_songinfo(a3),a3    ;MMD0song
  2243.     ENDC
  2244. IM_loop1    cmp.w    #3,d0
  2245.         ble.s    IM_noftune
  2246.         move.b    3(a0),126(a2)    ;InstrExt.finetune -> finetune
  2247. IM_noftune
  2248.     IFNE    MIDI
  2249.         cmp.w    #2,d0
  2250.         ble.s    IM_nsmnoff
  2251.         tst.b    2(a0)        ;suppress MIDI note off?
  2252.         beq.s    IM_nsmnoff
  2253.         bset    #7,inst_midich(a3)
  2254. IM_nsmnoff    addq.l    #8,a3        ;next instr
  2255.     ENDC
  2256.         move.b    1(a0),63(a2)    ;InstrExt.decay -> decay
  2257.         move.b    (a0),(a2)+    ;InstrExt.hold -> holdvals
  2258.         adda.w    d0,a0        ;ptr to next InstrExt
  2259.         dbf    d2,IM_loop1
  2260.         bra.s    IM_exit
  2261. IM_clrhlddec    move.w    #3*63-1,d0    ;no InstrExt => clear holdvals/decays
  2262. IM_loop2    clr.b    (a2)+
  2263.         dbf    d0,IM_loop2
  2264. IM_exit        movem.l    (sp)+,a2-a3/d2
  2265.         rts
  2266. ; *************************************************************************
  2267. ; InitPlayer() -- allocate interrupt, audio, serial port etc...
  2268. ; *************************************************************************
  2269. _InitPlayer:
  2270.     IFNE    MIDI
  2271.         bsr.w    _GetSerial
  2272.         tst.l    d0
  2273.         bne.s    IP_error
  2274.     ENDC
  2275.         bsr.w    _AudioInit
  2276.         tst.l    d0
  2277.         bne.s    IP_error
  2278.         rts
  2279. IP_error    bsr.s    _RemPlayer
  2280.         moveq    #-1,d0
  2281.         rts
  2282. ; *************************************************************************
  2283. ; RemPlayer() -- free interrupt, audio, serial port etc..
  2284. ; *************************************************************************
  2285. _RemPlayer:    move.b    _timeropen,d0
  2286.         beq.s    RP_notimer    ;timer is not ours
  2287.         bsr.s    _StopPlayer
  2288. RP_notimer:    bsr.w    _AudioRem
  2289.     IFNE    MIDI
  2290.         bsr.w    _FreeSerial
  2291.     ENDC
  2292.         rts
  2293. ; *************************************************************************
  2294. ; StopPlayer() -- stop music
  2295. ; *************************************************************************
  2296. _StopPlayer:    lea    DB,a1
  2297.         move.b    _timeropen-DB(a1),d0
  2298.         beq.s    SP_end        ;res. alloc fail.
  2299.     IFNE    CIAB
  2300.         movea.l    craddr-DB(a1),a0
  2301.         bclr    #0,(a0)        ;stop timer
  2302.     ENDC
  2303.         move.l    _module-DB(a1),d0
  2304.         beq.s    SP_nomod
  2305.         move.l    d0,a0
  2306.         clr.w    mmd_pstate(a0)
  2307.         clr.l    _module-DB(a1)
  2308. SP_nomod
  2309.     IFNE    MIDI
  2310.         clr.b    lastcmdbyte-DB(a1)
  2311.     ENDC
  2312.         bsr.w    SoundOff
  2313. SP_end        rts
  2314.  
  2315.  
  2316. _ContModule    tst.b    _timeropen
  2317.         beq.s    SP_end
  2318.         movea.l    craddr,a1
  2319.         bclr    #0,(a1)
  2320.         move.l    a0,-(sp)
  2321.         bsr.w    SoundOff
  2322.         move.l    (sp)+,a0
  2323.         moveq    #0,d0
  2324.         bra.s    contpoint
  2325. ; *************************************************************************
  2326. ; PlayModule(a0 = module)  -- initialize & play it!!
  2327. ; *************************************************************************
  2328. _PlayModule:    st    d0
  2329. contpoint    movem.l    a0/d0,-(sp)
  2330.         bsr    _InitModule
  2331.         movem.l    (sp)+,a0/d0
  2332.         move.l    a6,-(sp)
  2333.         lea    DB,a6
  2334.         tst.b    _timeropen-DB(a6)
  2335.         beq    PM_end        ;resource allocation failure
  2336.         move.l    a0,d1
  2337.         beq    PM_end        ;module failure
  2338.     IFNE    CIAB
  2339.         movea.l    craddr-DB(a6),a1
  2340.         bclr    #0,(a1)        ;stop timer...
  2341.     ENDC
  2342.         clr.l    _module-DB(a6)
  2343.     IFNE    MIDI
  2344.         clr.b    lastcmdbyte-DB(a6)
  2345.     ENDC
  2346.         move.w    _modnum,d1
  2347.         beq.s    PM_modfound
  2348. PM_nextmod    tst.l    mmd_expdata(a0)
  2349.         beq.s    PM_modfound
  2350.         move.l    mmd_expdata(a0),a1
  2351.         tst.l    (a1)
  2352.         beq.s    PM_modfound        ;no more modules here!
  2353.         move.l    (a1),a0
  2354.         subq.w    #1,d1
  2355.         bgt.s    PM_nextmod
  2356. PM_modfound    movea.l    mmd_songinfo(a0),a1        ;song
  2357.         move.b    msng_tempo2(a1),mmd_counter(a0)    ;init counter
  2358.         btst    #0,msng_flags(a1)
  2359.         bne.s    PM_filon
  2360.         bset    #1,$bfe001
  2361.         bra.s    PM_filset
  2362. PM_filon    bclr    #1,$bfe001
  2363. PM_filset    tst.b    d0
  2364.         beq.s    PM_noclr
  2365.         clr.l    mmd_pline(a0)
  2366.         clr.l    rptline-DB(a6)
  2367.         clr.w    blkdelay-DB(a6)
  2368. PM_noclr    move.w    mmd_pseqnum(a0),d1
  2369.         add.w    #msng_playseq,d1
  2370.         move.b    0(a1,d1.w),d1        ;get first playseq entry
  2371.         move.b    d1,mmd_pblock+1(a0)
  2372.         move.w    #-1,mmd_pstate(a0)
  2373.         move.l    a0,_module-DB(a6)
  2374.         btst    #5,msng_flags2(a1)    ;BPM?
  2375.         seq    bpmcounter-DB(a6)
  2376.     IFNE    CIAB
  2377.         move.w    msng_deftempo(a1),d0    ;get default tempo
  2378.         movea.l    craddr-DB(a6),a1
  2379.         bsr.w    _SetTempo    ;set default tempo
  2380.         bset    #0,(a1)        ;start timer => PLAY!!
  2381.     ENDC
  2382. PM_end        move.l    (sp)+,a6
  2383.         rts
  2384. ; *************************************************************************
  2385.  
  2386. _AudioInit:    movem.l    a4/a6/d2-d3,-(sp)
  2387.         lea    DB,a4
  2388.         moveq    #0,d2
  2389.         movea.l    4,a6
  2390. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ alloc signal bit
  2391.     IFNE    AUDDEV
  2392.         moveq    #1,d2
  2393.         moveq    #-1,d0
  2394.         jsr    -$14a(a6)    ;AllocSignal()
  2395.         tst.b    d0
  2396.         bmi.w    initerr
  2397.         move.b    d0,sigbitnum-DB(a4)
  2398. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ prepare IORequest
  2399.         lea    allocport-DB(a4),a1
  2400.         move.b    d0,15(a1)    ;set mp_SigBit
  2401.         move.l    a1,-(sp)
  2402.         suba.l    a1,a1
  2403.         jsr    -$126(a6)    ;FindTask(0)
  2404.         move.l    (sp)+,a1
  2405.         move.l    d0,16(a1)    ;set mp_SigTask
  2406.         lea    reqlist-DB(a4),a0
  2407.         move.l    a0,(a0)        ;NEWLIST begins...
  2408.         addq.l    #4,(a0)
  2409.         clr.l    4(a0)
  2410.         move.l    a0,8(a0)    ;NEWLIST ends...
  2411. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ open audio.device
  2412.         moveq    #2,d2
  2413.         lea    allocreq-DB(a4),a1
  2414.         lea    audiodevname-DB(a4),a0
  2415.         moveq    #0,d0
  2416.         moveq    #0,d1
  2417.         movea.l    4,a6
  2418.         jsr    -$1bc(a6)    ;OpenDevice()
  2419.         tst.b    d0
  2420.         bne.w    initerr
  2421.         st.b    audiodevopen-DB(a4)
  2422. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ open cia resource
  2423.         moveq    #3,d2
  2424.     ENDC
  2425.     IFNE    CIAB
  2426.         cmp.b    #50,$212(a6)    ;ExecBase->VBlankFrequency
  2427.         beq.s    init_pal
  2428.         move.l    #474326,timerdiv-DB(a4) ;Assume that CIA freq is 715 909 Hz
  2429.         move.l    #3579545/2,bpmdiv-DB(a4)
  2430. init_pal    moveq    #0,d3
  2431.         lea    cianame-DB(a4),a1
  2432.         move.b    #'a',3(a1)
  2433. open_ciares    moveq    #0,d0
  2434.         jsr    -$1f2(a6)    ;OpenResource()
  2435.         move.l    d0,_ciaresource
  2436.         beq.s    try_CIAB
  2437.         moveq    #4,d2
  2438.         move.l    d0,a6
  2439.         lea    timerinterrupt-DB(a4),a1
  2440.         moveq    #0,d0        ;Timer A
  2441.         jsr    -$6(a6)        ;AddICRVector()
  2442.         tst.l    d0
  2443.         beq.s    got_timer
  2444.         addq.l    #4,d3        ;add base addr index
  2445.         lea    timerinterrupt-DB(a4),a1
  2446.         moveq    #1,d0        ;Timer B
  2447.         jsr    -$6(a6)        ;AddICRVector()
  2448.         tst.l    d0
  2449.         beq.s    got_timer
  2450. try_CIAB    lea    cianame-DB(a4),a1
  2451.         cmp.b    #'a',3(a1)
  2452.         bne.s    initerr
  2453.         addq.b    #1,3(a1)
  2454.         moveq    #8,d3        ;CIAB base addr index = 8
  2455.         bra.w    open_ciares
  2456. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ attach interrupt
  2457. got_timer    lea    craddr+8-DB(a4),a6
  2458.         move.l    cia_addr(pc,d3.w),d0
  2459.         move.l    d0,(a6)
  2460.         sub.w    #$100,d0
  2461.         move.l    d0,-(a6)
  2462.         moveq    #2,d3        ;assume timer B
  2463.         btst    #9,d0        ;timer A or B ?
  2464.         bne.s    got_timerB
  2465.         subq.b    #1,d3        ;not timer B -> subtract 1
  2466.         add.w    #$100,d0    ;calc offset to timer control reg
  2467. got_timerB    add.w    #$900,d0
  2468.         move.l    d0,-(a6)
  2469.         move.l    d0,a0            ;get Control Register
  2470.         and.b    #%10000000,(a0)        ;clear CtrlReg bits 0 - 6
  2471.         move.b    d3,_timeropen-DB(a4)    ;d3: 1 = TimerA 2 = TimerB
  2472.     ENDC
  2473.     IFNE    VBLANK
  2474.         moveq    #5,d0        ;INTB_VERTB
  2475.         lea    timerinterrupt-DB(a4),a1
  2476.         jsr    -$a8(a6)    ;AddIntServer
  2477.         st    _timeropen-DB(a4)
  2478.     ENDC
  2479.         moveq    #0,d0
  2480. initret:    movem.l    (sp)+,a4/a6/d2-d3
  2481.         rts
  2482. initerr:    move.l    d2,d0
  2483.         bra.s    initret
  2484.  
  2485. cia_addr:    dc.l    $BFE501,$BFE701,$BFD500,$BFD700
  2486.  
  2487. _AudioRem:    movem.l    a5-a6,-(sp)
  2488.         lea    DB,a5
  2489.         moveq    #0,d0
  2490.         move.b    _timeropen,d0
  2491.         beq.s    rem1
  2492. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ remove interrupt
  2493.         move.l    _ciaresource,a6
  2494.         lea    timerinterrupt-DB(a5),a1
  2495.         subq.b    #1,d0
  2496.         jsr    -$c(a6)        ;RemICRVector
  2497. rem1:
  2498.     IFNE    AUDDEV
  2499.         movea.l    4,a6
  2500.         tst.b    audiodevopen-DB(a5)
  2501.         beq.s    rem2
  2502.         move.w    #$000f,$dff096    ;stop audio DMA
  2503. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ close audio.device
  2504.         lea    allocreq-DB(a5),a1
  2505.         jsr    -$1c2(a6)    ;CloseDevice()
  2506.         clr.b    audiodevopen-DB(a5)
  2507. rem2:        moveq    #0,d0
  2508.         move.b    sigbitnum-DB(a5),d0
  2509.         bmi.s    rem3
  2510. ;    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ free signal bit
  2511.         jsr    -$150(a6)    ;FreeSignal()
  2512.         st    sigbitnum-DB(a5)
  2513. rem3:
  2514.     ENDC
  2515.         movem.l    (sp)+,a5-a6
  2516.         rts
  2517.  
  2518.     IFNE    MIDI
  2519. _GetSerial:    movem.l    a5-a6,-(sp)    ;Get serial port for MIDI
  2520.         lea    DB,a5
  2521.         bsr.s    GetSer2
  2522.         tst.l    d0        ;got the port??
  2523.         beq.s    rgser        ;yes
  2524.         movea.l    4,a6        ;no..try to flush serial.device:
  2525.         jsr    -$84(a6)        ;Forbid
  2526.         lea    $15e(a6),a0        ;ExecBase->DeviceList
  2527.         lea    serdev-DB(a5),a1    ;"serial.device"
  2528.         jsr    -$114(a6)        ;FindName
  2529.         tst.l    d0
  2530.         beq.s    serdnotf        ;no serial.device!!
  2531.         move.l    d0,a1
  2532.         jsr    -$1b6(a6)        ;RemDevice
  2533. serdnotf:    jsr    -$8a(a6)        ;and Permit
  2534.         bsr.s    GetSer2        ;now try it again...
  2535. rgser:        movem.l    (sp)+,a5-a6
  2536.         rts
  2537.  
  2538. GetSer2:    movea.l    4,a6
  2539.         moveq    #0,d0
  2540.         lea    miscresname-DB(a5),a1
  2541.         jsr    -$1f2(a6)    ;OpenResource()
  2542.         move.l    d0,miscresbase-DB(a5)
  2543.         tst.l    d0
  2544.         beq.s    gserror
  2545.         move.l    d0,a6
  2546.         lea    medname-DB(a5),a1
  2547.         moveq    #0,d0        ;serial port
  2548.         jsr    -$6(a6)        ;AllocMiscResource()
  2549.         tst.l    d0
  2550.         bne.s    gserror
  2551.         lea    medname-DB(a5),a1
  2552.         moveq    #1,d0        ;serial bits
  2553.         jsr    -$6(a6)
  2554.         tst.l    d0
  2555.         beq.s    gs2_allocok
  2556.         moveq    #0,d0
  2557.         jsr    -$c(a6)        ;bits failed -> Free serial port
  2558.         bra.s    gserror
  2559. gs2_allocok    move.w    $dff01c,d0
  2560.         btst    #0,d0
  2561.         sne    intrson-DB(a5)
  2562.         moveq    #0,d0        ;TBE
  2563.         lea    serinterrupt-DB(a5),a1
  2564.         move.l    4,a6
  2565.         jsr    -$a2(a6)    ;SetIntVector()
  2566.         move.l    d0,prevtbe-DB(a5)
  2567.         move.w    #$8001,$dff09a    ;TBE on
  2568.         move.w    #114,$dff032    ;set baud rate (SERPER)
  2569.         st    serportalloc-DB(a5)
  2570.         moveq    #0,d0
  2571.         rts
  2572. gserror:    moveq    #-1,d0
  2573.         rts
  2574.  
  2575. _FreeSerial:    movem.l    a5-a6,-(sp)
  2576.         lea    DB,a5
  2577.         tst.l    miscresbase-DB(a5)
  2578.         beq.s    retfs
  2579.         tst.b    serportalloc-DB(a5)
  2580.         beq.s    retfs
  2581. wmb_loop    move.w    $dff018,d0    ;WAIT until all data sent
  2582.         btst    #12,d0        ;test TSRE bit of SERDAT
  2583.         beq.s    wmb_loop
  2584.         move.w    #$0001,$dff09a    ;disable TBE
  2585.         movea.l    4,a6
  2586.         move.l    prevtbe-DB(a5),a1
  2587.         moveq    #0,d0
  2588.         jsr    -$a2(a6)    ;SetIntVector()
  2589. fs_noptbe    movea.l    miscresbase-DB(a5),a6
  2590.         moveq    #0,d0        ;serial port
  2591.         jsr    -$c(a6)        ;FreeMiscResource()
  2592.         moveq    #1,d0        ;serial bits
  2593.         jsr    -$c(a6)
  2594.         clr.b    serportalloc-DB(a5)
  2595.         clr.b    lastcmdbyte-DB(a5)
  2596. retfs:        movem.l    (sp)+,a5-a6
  2597.         rts
  2598.  
  2599. ; Message number in d0.
  2600. _InitMIDIDump:    tst.b    serportalloc
  2601.         beq.s    idd_rts
  2602.         movem.l    a5/a6,-(sp)    ;a1 = data pointer, d1 = length
  2603.         lea    DB,a5
  2604.         movea.l    4,a6            ;ExecBase
  2605.         jsr    -$78(a6)        ;Disable()
  2606.         cmp.w    #16,dqentries-DB(a5)    ;dump queue full?
  2607.         bge.s    idd_exit        ;exit without doing anything
  2608.         lea    dqwriteptr-DB(a5),a1
  2609.         movea.l    (a1),a0
  2610.         move.w    d0,(a0)+        ;store message number
  2611.         cmpa.l    a1,a0            ;queue end?
  2612.         bne.s    idd_noresetbuff
  2613.         lea    dumpqueue-DB(a5),a0    ;reset write pointer
  2614. idd_noresetbuff    move.l    a0,(a1)            ;and write it back.
  2615.         addq.w    #1,dqentries-DB(a5)
  2616.         tst.b    sysx-DB(a5)        ;already sending data?
  2617.         bne.s    idd_exit        ;yes. Don't initiate new send.
  2618.         clr.b    lastcmdbyte-DB(a5)
  2619.         bsr    StartNewDump
  2620.         move.w    $dff018,d0        ;SERDATR
  2621.         btst    #13,d0
  2622.         beq.s    idd_exit
  2623.         move.w    #$8001,$dff09c        ;request TBE
  2624. idd_exit    jsr    -$7e(a6)        ;Enable()
  2625.         movem.l    (sp)+,a5/a6
  2626. idd_rts        rts
  2627.  
  2628. SerIntHandler:    move.w    #$4000,$9a(a0)    ;disable..(Interrupts are enabled anyway)
  2629.         move.w    #1,$9c(a0)            ;clear intreq bit
  2630.         tst.b    sysx-buffptr(a1)        ;sysx??
  2631.         bne.s    sih_sysx
  2632.         move.b    bytesinbuff-buffptr(a1),d0    ;bytesinbuff
  2633.         beq.s    exsih                ;buffer empty
  2634.         movea.l    readbuffptr-buffptr(a1),a5    ;get buffer read pointer
  2635.         move.w    #$100,d1            ;Stop bit
  2636.         move.b    (a5)+,d1            ;get byte
  2637.         move.w    d1,$30(a0)            ;and push it to SERDAT
  2638.         cmpa.l    a1,a5                ;shall we reset ptr??
  2639.         bne.s    norrbuffptr            ;not yet..
  2640.         lea    -128(a1),a5
  2641. norrbuffptr    subq.b    #1,d0                ;one less bytes in buffer
  2642.         move.b    d0,bytesinbuff-buffptr(a1)    ;remember it
  2643.         move.l    a5,readbuffptr-buffptr(a1)    ;push new read ptr back
  2644. exsih        move.w    #$c000,$9a(a0)
  2645.         rts
  2646. sih_sysx    move.w    #$100,d1
  2647.         movea.l    sysxptr-buffptr(a1),a5    ;data pointer
  2648.         move.b    (a5)+,d1
  2649.         move.l    a5,sysxptr-buffptr(a1)
  2650.         move.w    d1,$30(a0)        ;-> SERDAT
  2651.         subq.l    #1,sysxleft-buffptr(a1)    ;sub data left length
  2652.         bne.s    exsih        ;not 0w
  2653.         lea    DB,a5
  2654.         clr.b    lastcmdbyte-DB(a5)
  2655.         bsr.s    StartNewDump
  2656.         bra.s    exsih
  2657.  
  2658. StartNewDump:    tst.w    dqentries-DB(a5)    ;queue empty?
  2659.         beq.s    snd_exit2
  2660.         movea.l    dqreadptr-DB(a5),a1    ;get read pointer
  2661.         move.w    (a1)+,d0        ;get message number (D0)
  2662.         cmpa.l    #dqwriteptr,a1        ;queue end?
  2663.         bne.s    snd_noresetbuff
  2664.         lea    dumpqueue-DB(a5),a1    ;reset write pointer
  2665. snd_noresetbuff    move.l    a1,dqreadptr-DB(a5)    ;and write it back.
  2666.         subq.w    #1,dqentries-DB(a5)
  2667. ; then attempt to search the given message (# in D0)
  2668.         move.l    _module-DB(a5),d1
  2669.         beq.s    StartNewDump
  2670.         move.l    d1,a1
  2671.         move.l    mmd_expdata(a1),d1
  2672.         beq.s    StartNewDump
  2673.         move.l    d1,a1
  2674.         move.l    52(a1),d1        ;exp_dump
  2675.         beq.s    StartNewDump
  2676.         move.l    d1,a1
  2677.         cmp.w    (a1),d0
  2678.         bge.s    StartNewDump
  2679.         addq.l    #8,a1            ;points to MMDDump ptr table
  2680.         add.w    d0,d0
  2681.         add.w    d0,d0            ;number *= 4
  2682.         adda.w    d0,a1
  2683.         movea.l    (a1),a1
  2684. ; initialize send variables (msg addr. in A0)
  2685. snd_found    move.l    (a1)+,sysxleft-DB(a5)    ;length
  2686.         move.l    (a1),sysxptr-DB(a5)    ;data pointer
  2687.         st    sysx-DB(a5)
  2688.         rts
  2689. snd_exit2    clr.b    sysx-DB(a5)        ;finish dump
  2690.         rts
  2691.  
  2692. _AddMIDIData    move.l    a6,-(sp)
  2693.         lea    DB,a6
  2694.         bsr.s    _AddMIDId
  2695.         move.l    (sp)+,a6
  2696.         rts
  2697.  
  2698. _AddMIDId    movem.l    a2-a3/a5,-(sp)
  2699.         tst.b    serportalloc-DB(a6)
  2700.         beq.s    retamd1
  2701.         movea.l    4,a5
  2702.         lea    $dff09a,a3
  2703.         move.w    #$4000,(a3)    ;Disable interrupts
  2704.         addq.b    #1,$126(a5)    ;ExecBase->IDNestCnt
  2705.         lea    buffptr-DB(a6),a2    ;end of buffer (ptr)
  2706.         move.w    -130(a3),d1    ;-130(a3) = $dff018 (SERDATR)
  2707.         btst    #13,d1
  2708.         beq.s    noTBEreq
  2709.         move.w    #$8001,2(a3)    ;request TBE [2(a3) = $dff09c]
  2710. noTBEreq    movea.l    (a2),a1        ;buffer pointer
  2711. adddataloop    move.b    (a0)+,d1    ;get byte
  2712.         bpl.s    norscheck    ;this isn't a status byte
  2713.         cmp.b    #$ef,d1        ;ignore system messages
  2714.         bhi.s    norscheck
  2715.         cmp.b    lastcmdbyte-DB(a6),d1    ;same as previos status byte?
  2716.         beq.s    samesb            ;yes, skip
  2717.         move.b    d1,lastcmdbyte-DB(a6)    ;no, don't skip but store.
  2718. norscheck    move.b    d1,(a1)+        ;push to midi send buffer
  2719.         addq.b    #1,8(a2)
  2720. samesb        cmpa.l    a2,a1            ;end of buffer??
  2721.         bne.s    noresbuffptr        ;no.
  2722.         lea    sendbuffer-DB(a6),a1    ;reset
  2723. noresbuffptr    subq.b    #1,d0
  2724.         bne.s    adddataloop
  2725.         move.l    a1,(a2)            ;push back new buffer ptr
  2726.         subq.b    #1,$126(a5)
  2727.         bge.s    retamd1
  2728.         move.w    #$c000,(a3)    ;enable interrupts again
  2729. retamd1        movem.l    (sp)+,a2-a3/a5
  2730.         rts
  2731.     ENDC
  2732.  
  2733.         DATA
  2734. DB:        ;Data base pointer
  2735.     IFNE    MIDI
  2736. sendbuffer    ds.b    128
  2737. buffptr        dc.l    sendbuffer
  2738. readbuffptr    dc.l    sendbuffer
  2739. bytesinbuff    dc.b    0
  2740.         dc.b    0
  2741. sysx        dc.b    0
  2742. lastcmdbyte    dc.b    0
  2743. sysxptr        dc.l    0
  2744. sysxleft    dc.l    0
  2745. dumpqueue    ds.w    16
  2746. dqwriteptr    dc.l    dumpqueue
  2747. dqreadptr    dc.l    dumpqueue
  2748. dqentries    dc.w    0
  2749.     ENDC
  2750. miscresbase    dc.l    0
  2751. timerdiv    dc.l    470000
  2752.     IFNE    AUDDEV
  2753. audiodevopen    dc.b    0
  2754. sigbitnum    dc.b    -1
  2755.     ENDC
  2756.     IFNE    MIDI
  2757. serportalloc    dc.b    0
  2758.     ENDC
  2759.         even
  2760.     IFNE    MIDI
  2761. preschgdata    dc.w    0
  2762. noteondata    dc.l    0
  2763.     ENDC
  2764. _module        dc.l    0
  2765. dmaonmsk    dc.w    0 ;\_May not be
  2766.     IFNE    MIDI
  2767. bytesinnotebuff    dc.w    0 ;/ separated!
  2768. noteonbuff    ds.b    18*3
  2769.         even
  2770. intrson        dc.b    0,0
  2771. prevtbe        dc.l    0
  2772.     ENDC
  2773.     IFNE    CIAB
  2774. _ciaresource    dc.l    0
  2775. craddr        dc.l    0
  2776.         dc.l    0    ;tloaddr
  2777.         dc.l    0    ;thiaddr
  2778.     ENDC
  2779. timerinterrupt    dc.w    0,0,0,0,0
  2780.         dc.l    timerintname,DB
  2781.         dc.l    _IntHandler
  2782.     IFNE    MIDI
  2783. serinterrupt    dc.w    0,0,0,0,0
  2784.         dc.l    serintname,buffptr,SerIntHandler
  2785.     ENDC
  2786.     IFNE    AUDDEV
  2787. allocport    dc.l    0,0    ;succ, pred
  2788.         dc.b    4,0    ;NT_MSGPORT
  2789.         dc.l    0    ;name
  2790.         dc.b    0,0    ;flags = PA_SIGNAL
  2791.         dc.l    0    ;task
  2792. reqlist        dc.l    0,0,0    ;list head, tail and tailpred
  2793.         dc.b    5,0
  2794. allocreq    dc.l    0,0
  2795.         dc.b    0,127    ;NT_UNKNOWN, use maximum priority (127)
  2796.         dc.l    0,allocport    ;name, replyport
  2797.         dc.w    68        ;length
  2798.         dc.l    0    ;io_Device
  2799.         dc.l    0    ;io_Unit
  2800.         dc.w    0    ;io_Command
  2801.         dc.b    0,0    ;io_Flags, io_Error
  2802.         dc.w    0    ;ioa_AllocKey
  2803.         dc.l    sttempo    ;ioa_Data
  2804.         dc.l    1    ;ioa_Length
  2805.         dc.w    0,0,0    ;ioa_Period, Volume, Cycles
  2806.         dc.w    0,0,0,0,0,0,0,0,0,0    ;ioa_WriteMsg
  2807. audiodevname    dc.b    'audio.device',0
  2808.     ENDC
  2809.     IFNE    CIAB
  2810. cianame        dc.b    'ciax.resource',0
  2811. _timeropen    dc.b    0
  2812.     ENDC
  2813. timerintname    dc.b    'OMEDTimerInterrupt',0
  2814.     IFNE    MIDI
  2815. serintname    dc.b    'OMEDSerialInterrupt',0
  2816. miscresname    dc.b    'misc.resource',0
  2817. serdev        dc.b    'serial.device',0
  2818. medname        dc.b    'OctaMED Pro modplayer',0
  2819.     ENDC
  2820.         even
  2821.     IFNE    MIDI
  2822. midiresd    dc.b    $e0,$00,$40,$b0,$01,$00
  2823.  
  2824. midicontrnum    ds.b    16
  2825.  
  2826. prevmidicpres    dc.l    0,0,0,0 ; 16 bytes
  2827.  
  2828. prevmidipbend    dc.w    $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
  2829.         dc.w    $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
  2830.     ENDC
  2831. ; TRACK-data structures (see definitions at the end of this file)
  2832. t03d        ds.b    22
  2833.         dc.l    $dff0a0
  2834.         ds.b    71
  2835.         dc.b    $ff
  2836.         ds.b    22
  2837.         dc.l    $dff0b0
  2838.         ds.b    71
  2839.         dc.b    $ff
  2840.         ds.b    22
  2841.         dc.l    $dff0c0
  2842.         ds.b    71
  2843.         dc.b    $ff
  2844.         ds.b    22
  2845.         dc.l    $dff0d0
  2846.         ds.b    71
  2847.         dc.b    $ff
  2848. t415d        ds.b    4*T415SZ
  2849. t815d        ds.b    8*T415SZ    ;8 bytes * 12 tracks = 96 bytes
  2850. trackdataptrs    dc.l    t03d,t03d+T03SZ,t03d+2*T03SZ,t03d+3*T03SZ
  2851.         dc.l    t415d,t415d+T415SZ,t415d+2*T415SZ,t415d+3*T415SZ
  2852.         dc.l    t815d,t815d+T415SZ,t815d+2*T415SZ,t815d+3*T415SZ
  2853.         dc.l    t815d+4*T415SZ,t815d+5*T415SZ,t815d+6*T415SZ
  2854.         dc.l    t815d+7*T415SZ
  2855.  
  2856. nextblock    dc.b    0 ;\ DON'T SEPARATE
  2857. nxtnoclrln    dc.b    0 :/
  2858. numtracks    dc.w    0 ;\ DON'T SEPARATE
  2859. numlines    dc.w    0 ;/
  2860. nextblockline    dc.w    0
  2861. rptline        dc.w    0 ;\ DON'T SEPARATE
  2862. rptcounter    dc.w    0 ;/
  2863. blkdelay    dc.w    0    ;block delay (PT PatternDelay)
  2864. bpmcounter    dc.w    0
  2865. bpmdiv        dc.l    3546895/2
  2866.  
  2867. holdvals    ds.b 63
  2868. decays        ds.b 63
  2869. finetunes    ds.b 63
  2870.  
  2871. ; Below are the period tables. There's one table for each finetune position.
  2872.     IFNE    SYNTH
  2873.     dc.w    3424,3232,3048,2880,2712,2560,2416,2280,2152,2032,1920,1812
  2874.     dc.w    1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906
  2875.     ENDC
  2876. per0    dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  2877.     dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  2878.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2879.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2880.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2881.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2882.     IFNE    SYNTH
  2883.     dc.w    3400,3209,3029,2859,2699,2547,2404,2269,2142,2022,1908,1801
  2884.     dc.w    1700,1605,1515,1430,1349,1274,1202,1135,1071,1011,954,901
  2885.     ENDC
  2886. per1    dc.w    850,802,757,715,674,637,601,567,535,505,477,450
  2887.     dc.w    425,401,379,357,337,318,300,284,268,253,239,225
  2888.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2889.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2890.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2891.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2892.     IFNE    SYNTH
  2893.     dc.w    3376,3187,3008,2839,2680,2529,2387,2253,2127,2007,1895,1788
  2894.     dc.w    1688,1593,1504,1419,1340,1265,1194,1127,1063,1004,947,894
  2895.     ENDC
  2896. per2    dc.w    844,796,752,709,670,632,597,563,532,502,474,447
  2897.     dc.w    422,398,376,355,335,316,298,282,266,251,237,224
  2898.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2899.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2900.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2901.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2902.     IFNE    SYNTH
  2903.     dc.w    3352,3164,2986,2819,2660,2511,2370,2237,2112,1993,1881,1776
  2904.     dc.w    1676,1582,1493,1409,1330,1256,1185,1119,1056,997,941,888
  2905.     ENDC
  2906. per3    dc.w    838,791,746,704,665,628,592,559,528,498,470,444
  2907.     dc.w    419,395,373,352,332,314,296,280,264,249,235,222
  2908.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2909.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2910.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2911.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2912.     IFNE    SYNTH
  2913.     dc.w    3328,3141,2965,2799,2641,2493,2353,2221,2097,1979,1868,1763
  2914.     dc.w    1664,1571,1482,1399,1321,1247,1177,1111,1048,989,934,881
  2915.     ENDC
  2916. per4    dc.w    832,785,741,699,660,623,588,555,524,495,467,441
  2917.     dc.w    416,392,370,350,330,312,294,278,262,247,233,220
  2918.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2919.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2920.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2921.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2922.     IFNE    SYNTH
  2923.     dc.w    3304,3119,2944,2778,2622,2475,2336,2205,2081,1965,1854,1750
  2924.     dc.w    1652,1559,1472,1389,1311,1238,1168,1103,1041,982,927,875
  2925.     ENDC
  2926. per5    dc.w    826,779,736,694,655,619,584,551,520,491,463,437
  2927.     dc.w    413,390,368,347,328,309,292,276,260,245,232,219
  2928.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2929.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2930.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2931.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2932.     IFNE    SYNTH
  2933.     dc.w    3280,3096,2922,2758,2603,2457,2319,2189,2066,1950,1841,1738
  2934.     dc.w    1640,1548,1461,1379,1302,1229,1160,1095,1033,975,920,869
  2935.     ENDC
  2936. per6    dc.w    820,774,730,689,651,614,580,547,516,487,460,434
  2937.     dc.w    410,387,365,345,325,307,290,274,258,244,230,217
  2938.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2939.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2940.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2941.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2942.     IFNE    SYNTH
  2943.     dc.w    3256,3073,2901,2738,2584,2439,2302,2173,2051,1936,1827,1725
  2944.     dc.w    1628,1537,1450,1369,1292,1220,1151,1087,1026,968,914,862
  2945.     ENDC
  2946. per7    dc.w    814,768,725,684,646,610,575,543,513,484,457,431
  2947.     dc.w    407,384,363,342,323,305,288,272,256,242,228,216
  2948.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2949.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2950.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2951.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2952.     IFNE    SYNTH
  2953.     dc.w    3628,3424,3232,3051,2880,2718,2565,2421,2285,2157,2036,1922
  2954.     dc.w    1814,1712,1616,1525,1440,1359,1283,1211,1143,1079,1018,961
  2955.     ENDC
  2956. per_8    dc.w    907,856,808,762,720,678,640,604,570,538,508,480
  2957.     dc.w    453,428,404,381,360,339,320,302,285,269,254,240
  2958.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2959.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2960.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2961.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2962.     IFNE    SYNTH
  2963.     dc.w    3588,3387,3197,3017,2848,2688,2537,2395,2260,2133,2014,1901
  2964.     dc.w    1794,1693,1598,1509,1424,1344,1269,1197,1130,1067,1007,950
  2965.     ENDC
  2966. per_7    dc.w    900,850,802,757,715,675,636,601,567,535,505,477
  2967.     dc.w    450,425,401,379,357,337,318,300,284,268,253,238
  2968.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2969.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2970.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2971.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2972.     IFNE    SYNTH
  2973.     dc.w    3576,3375,3186,3007,2838,2679,2529,2387,2253,2126,2007,1894
  2974.     dc.w    1788,1688,1593,1504,1419,1339,1264,1193,1126,1063,1003,947
  2975.     ENDC
  2976. per_6    dc.w    894,844,796,752,709,670,632,597,563,532,502,474
  2977.     dc.w    447,422,398,376,355,335,316,298,282,266,251,237
  2978.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2979.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2980.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2981.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2982.     IFNE    SYNTH
  2983.     dc.w    3548,3349,3161,2984,2816,2658,2509,2368,2235,2110,1991,1879
  2984.     dc.w    1774,1674,1580,1492,1408,1329,1254,1184,1118,1055,996,940
  2985.     ENDC
  2986. per_5    dc.w    887,838,791,746,704,665,628,592,559,528,498,470
  2987.     dc.w    444,419,395,373,352,332,314,296,280,264,249,235
  2988.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2989.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2990.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2991.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2992.     IFNE    SYNTH
  2993.     dc.w    3524,3326,3140,2963,2797,2640,2492,2352,2220,2095,1978,1867
  2994.     dc.w    1762,1663,1570,1482,1399,1320,1246,1176,1110,1048,989,933
  2995.     ENDC
  2996. per_4    dc.w    881,832,785,741,699,660,623,588,555,524,494,467
  2997.     dc.w    441,416,392,370,350,330,312,294,278,262,247,233
  2998.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2999.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3000.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3001.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  3002.     IFNE    SYNTH
  3003.     dc.w    3500,3304,3118,2943,2778,2622,2475,2336,2205,2081,1964,1854
  3004.     dc.w    1750,1652,1559,1472,1389,1311,1237,1168,1102,1041,982,927
  3005.     ENDC
  3006. per_3    dc.w    875,826,779,736,694,655,619,584,551,520,491,463
  3007.     dc.w    437,413,390,368,347,328,309,292,276,260,245,232
  3008.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3009.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3010.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3011.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  3012.     IFNE    SYNTH
  3013.     dc.w    3472,3277,3093,2920,2756,2601,2455,2317,2187,2064,1949,1839
  3014.     dc.w    1736,1639,1547,1460,1378,1301,1228,1159,1094,1032,974,920
  3015.     ENDC
  3016. per_2    dc.w    868,820,774,730,689,651,614,580,547,516,487,460
  3017.     dc.w    434,410,387,365,345,325,307,290,274,258,244,230
  3018.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3019.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3020.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3021.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  3022.     IFNE    SYNTH
  3023.     dc.w    3448,3254,3072,2899,2737,2583,2438,2301,2172,2050,1935,1827
  3024.     dc.w    1724,1627,1536,1450,1368,1292,1219,1151,1086,1025,968,913
  3025.     ENDC
  3026. per_1    dc.w    862,814,768,725,684,646,610,575,543,513,484,457
  3027.     dc.w    431,407,384,363,342,323,305,288,272,256,242,228
  3028.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3029.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3030.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3031.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  3032.  
  3033. _periodtable
  3034.     dc.l    per_8,per_7,per_6,per_5,per_4,per_3,per_2,per_1,per0
  3035.     dc.l    per1,per2,per3,per4,per5,per6,per7
  3036.  
  3037.     IFND    __G2
  3038.         section "datachip",data,chip ;for A68k
  3039.     ENDC
  3040.     IFD    __G2
  3041.         section "datachip",data_c ;this is for Devpac 2
  3042.     ENDC
  3043.         XDEF    _modnum
  3044.     IFNE    EASY
  3045. easymod        INCBIN    "module"    ;<<<<< MODULE NAME HERE!
  3046.     ENDC
  3047. _chipzero    dc.l    0
  3048. _modnum        dc.w    0    ;number of module to play
  3049.  
  3050. ; the track-data structure definition:
  3051. trk_prevnote    EQU    0    ;previous note number
  3052. trk_previnstr    EQU    1    ;previous instrument number
  3053. trk_prevvol    EQU    2    ;previous volume
  3054. trk_prevmidich    EQU    3    ;previous MIDI channel
  3055. trk_cmd        EQU    4    ;command (the 3rd number from right)
  3056. trk_cmdqual    EQU    5    ;command qualifier (infobyte, databyte..)
  3057. trk_prevmidin    EQU    6    ;previous MIDI note
  3058. trk_noteoffcnt    EQU    7    ;note-off counter (hold)
  3059. trk_inithold    EQU    8    ;default hold for this instrument
  3060. trk_initdecay    EQU    9    ;default decay for....
  3061. trk_stransp    EQU    10    ;instrument transpose
  3062. trk_finetune    EQU    11    ;finetune
  3063. trk_soffset    EQU    12    ;new sample offset
  3064. trk_previnstra    EQU    14    ;address of the previous instrument data
  3065. trk_trackvol    EQU    18
  3066. ;    the following data only on tracks 0 - 3
  3067. trk_prevper    EQU    20    ;previous period
  3068. trk_audioaddr    EQU    22    ;hardware audio channel base address
  3069. trk_sampleptr    EQU    26    ;pointer to sample
  3070. trk_samplelen    EQU    30    ;length (>> 1)
  3071. trk_porttrgper    EQU    32    ;portamento (cmd 3) target period
  3072. trk_vibshift    EQU    34    ;vibrato shift for ASR instruction
  3073. trk_vibrspd    EQU    35    ;vibrato speed/size (cmd 4 qualifier)
  3074. trk_vibrsz    EQU    36    ;vibrato size
  3075. trk_synthptr    EQU    38    ;pointer to synthetic/hybrid instrument
  3076. trk_arpgoffs    EQU    42    ;SYNTH: current arpeggio offset
  3077. trk_arpsoffs    EQU    44    ;SYNTH: arpeggio restart offset
  3078. trk_volxcnt    EQU    46    ;SYNTH: volume execute counter
  3079. trk_wfxcnt    EQU    47    ;SYNTH: waveform execute counter
  3080. trk_volcmd    EQU    48    ;SYNTH: volume command pointer
  3081. trk_wfcmd    EQU    50    ;SYNTH: waveform command pointer
  3082. trk_volwait    EQU    52    ;SYNTH: counter for WAI (volume list)
  3083. trk_wfwait    EQU    53    ;SYNTH: counter for WAI (waveform list)
  3084. trk_synthvibspd    EQU    54    ;SYNTH: vibrato speed
  3085. trk_wfchgspd    EQU    56    ;SYNTH: period change
  3086. trk_perchg    EQU    58    ;SYNTH: curr. period change from trk_prevper
  3087. trk_envptr    EQU    60    ;SYNTH: envelope waveform pointer
  3088. trk_synvibdep    EQU    64    ;SYNTH: vibrato depth
  3089. trk_synvibwf    EQU    66       ;SYNTH: vibrato waveform
  3090. trk_synviboffs    EQU    70    ;SYNTH: vibrato pointer
  3091. trk_initvolxspd    EQU    72    ;SYNTH: volume execute speed
  3092. trk_initwfxspd    EQU    73    ;SYNTH: waveform execute speed
  3093. trk_volchgspd    EQU    74    ;SYNTH: volume change
  3094. trk_prevnote2    EQU    75    ;SYNTH: previous note
  3095. trk_synvol    EQU    76    ;SYNTH: current volume
  3096. trk_synthtype    EQU    77    ;>0 = synth, -1 = hybrid, 0 = no synth
  3097. trk_periodtbl    EQU    78    ;pointer to period table
  3098. trk_prevportspd    EQU    82    ;portamento (cmd 3) speed
  3099. trk_decay    EQU    84    ;decay
  3100. trk_fadespd    EQU    85    ;decay speed
  3101. trk_envrestart    EQU    86    ;SYNTH: envelope waveform restart point
  3102. trk_envcount    EQU    90    ;SYNTH: envelope counter
  3103. trk_split    EQU    91    ;0 = this channel not splitted (OctaMED V2)
  3104. trk_vibroffs    EQU    92    ;vibrato table offset \ DON'T SEPARATE
  3105. trk_tremoffs    EQU    93    ;tremolo table offset /
  3106. trk_tremsz    EQU    94    ;tremolo size
  3107. trk_tremspd    EQU    96    ;tremolo speed
  3108. trk_tempvol    EQU    97    ;temporary volume (for tremolo)
  3109.         END
  3110.